Comments (8)
@purain
手动实现 call 的函数中使用了 context 的 fn 属性,如果传入的参数 context 中本来就有 fn 属性且调用函数 test 中使用到 fn 的话怕是会出错。比如
function test(arg1, arg2){
console.log(arg1,arg2);
console.log(this.a, this.fn);
}
test.call2({
a: 'a',
fn: 'b'
}, 1, 2);
这里确实有问题,输出是:
1 2
a function test(arg1, arg2){
console.log(arg1,arg2);
console.log(this.a, this.fn);
}
原因在于手动实现的call
修改了上下文fn
,进入函数打印,此时fn
不再是b
,而是函数本身。目前没有好的办法,可以将call2
的fn
字段换成更不常用的__fn__
,或者使用es6的Symbol
语法。
修正版:
Function.prototype.call2 = function(context) {
if (typeof this !== "function") {
throw new TypeError("Error");
}
context = context || window;
const fn = Symbol('fn');
context[fn] = this;
const args = [...arguments].slice(1);
const result = context[fn](...args);
delete context[fn];
return result;
};
from blog.
手动实现 call 的函数中使用了 context 的 fn 属性,如果传入的参数 context 中本来就有 fn 属性且调用函数 test 中使用到 fn 的话怕是会出错。比如
function test(arg1, arg2){
console.log(arg1,arg2);
console.log(this.a, this.fn);
}
test.call2({
a: 'a',
fn: 'b'
}, 1, 2);
from blog.
关于深拷贝那段,我在网上看到很多下面的代码,但是我不知道哪里有坑,用了楼主的示例结果也没问题。
function deepCopy(obj){
let result = Array.isArray(obj) ? [] : {};
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key] && typeof obj[key] === 'object'){
result[key] = deepCopy(obj[key]);
}else{
result[key] = obj[key];
}
}
}
return result;
}
from blog.
它的没问题,而且实现的比我的精简多了。不过同样没考虑“循环引用”的问题。
@purain
关于深拷贝那段,我在网上看到很多下面的代码,但是我不知道哪里有坑,用了楼主的示例结果也没问题。
function deepCopy(obj){
let result = Array.isArray(obj) ? [] : {};
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(obj[key] && typeof obj[key] === 'object'){
result[key] = deepCopy(obj[key]);
}else{
result[key] = obj[key];
}
}
}
return result;
}
from blog.
//deepClone
typeof null === 'object' //true
from blog.
//deepClone typeof null === 'object' //true
如果obj[key] = null的话, obj[key] && typeof obj[key] === 'object 为false
from blog.
实现call/apply方法还是有一些不足的。给context添加额外属性会造成调用方法时,如果涉及到例如console.log(this)
操作会输出额外属性。我查到的方法是将函数转换成字符串, 并将其中的this
替换为context
,然后使用eval
方法转换成新函数。但是这样又涉及到使用正则判断this
串是否为变量this
,以及闭包外层变量被引用或context与闭包内变量重名问题。较难实现。
另外Function.prototype.call
的参数1,若为空,null
,undefined
,则绑定上下文至Window
。若为基本类型例如1,则绑定至new Number(1)
,这里的context赋值我是用
context = arguments[0] instanceof Object ? arguments[0] : new arguments[0].__proto__.constructor(arguments[0]);
来实现的。
from blog.
使用 ES5 实现的双向绑定有点小问题。功能上完全可以, 但是obj可以直接定义一个空对象。
get函数也有点小问题, value 没有定义, 这样的话想要访问 obj.value 的时候是会报错的。并且 get 与 set 一般都是用来创建伪属性的, 最好不要直接设置在真实属性上。
另外在 set 中, 不需要再去改变 input 的值了, 因为在输入的时候 input 的值就改变过了。
建议改成如下代码:
const obj = {};
// ...
Object.defineProperty(obj, 'value', {
get: () => {
return document.querySelector('input').value;
},
set: (newValue) => {
document.querySelector("#value").innerHTML = newValue;
}
})
from blog.
Related Issues (20)
- 「评论」JavaScript版 · 剑指offer HOT 7
- 「评论」无声半年:面试、实习和生活总结 HOT 12
- 「评论」参与协作
- 「评论」redis热key,缓存穿透,击穿,集群等问题研究
- 「评论」FileAPI 文件操作实战
- 「评论」字体特效 HOT 3
- 「评论」输入框特效 HOT 3
- 「评论」按钮特效
- 「评论」Loader特效·基础篇
- 「评论」Loader特效·进阶篇
- 「评论」基于实时数据库:在线对战五子棋小游戏
- 「评论」实战篇:当Koa遇上Typescript的时候~
- 「评论」基础篇:TypeScript用法与实战 HOT 5
- 关于Gitalk和Vueress的问题! HOT 3
- 「评论」React Router 常见问题汇总
- Gitalk HOT 2
- 命令模式 es6实现
- 求16篇webpack教程 HOT 1
- 【提问】404汇总 HOT 2
- xin-tan老博客的那个技术栈目录很棒啊,但是找不到了
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.