我是javascript的新手,我正在尝试实现一个复杂的数据结构,需要修改各种函数内的范围。然后,我遇到了function.prototype.bind()
。起初,我认为它非常有用。但是,有些结果是出乎意料的。所以,我写了一个测试的演示代码,这是代码。
(function () {
this.t = 9.8765432
this.a = (function(){
this.t = 3.14159
this.b = (function(){return this.t;}).bind(this)
this.c = (function(){
this.t=1.23456
this.d=(function(){return t;}).bind(this)
return this
})()
return this
})()
console.log(this.a.b()) //My guess was 3.14159, at the end it is 1.23456
console.log((this.a.b.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456
console.log(this.a.c.d()) //My guess was 1.23456, at the end it is 1.23456
console.log((this.a.c.d.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456
return this
})();
可悲的是,我猜错了所有结果。这表明我对此功能缺乏足够的了解。任何人都可以向我解释一下吗?
答案 0 :(得分:3)
您没有为this
创建任何对象来引用。因此,this
只是在代码中的任何地方引用全局window
对象(在严格模式下它将是undefined
)。由于您只有一个对象,因此您只有一个t
属性,该属性最近被赋值为1.23456
。之前的作业被最近的作业覆盖。
在每个范围内使用new关键字而不是IIFE尝试测试。这将为不同范围的this
创建三个单独的对象,而不是使用全局对象:
new function () {
this.t = 9.8765432
this.a = new function(){
this.t = 3.14159;
this.b = function(){return this.t;}.bind(this);
this.c = new function(){
this.t = 1.23456;
this.d = function(){return this.t;}.bind(this);
return this;
};
return this;
};
console.log( this.a.b() ); // My guess was 3.14159
console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
console.log( this.a.c.d() ); // My guess was 1.23456
console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432
return this;
};
您的第一次和第三次猜测都是正确的。如果函数尚未绑定,那么您的第二次和第四次猜测将是正确的。在已绑定的函数上调用bind
对它没有影响。删除内部调用bind将为您提供您期望的内容:
new function () {
this.t = 9.8765432
this.a = new function(){
this.t = 3.14159;
this.b = function(){return this.t;};
this.c = new function(){
this.t = 1.23456;
this.d = function(){return this.t;};
return this;
};
return this;
};
console.log( this.a.b() ); // My guess was 3.14159
console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
console.log( this.a.c.d() ); // My guess was 1.23456
console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432
return this;
};