我在 JavaScript 中看到过很多这样的事情,我记得找出原因,但我不记得答案了。
我猜这与范围和在“类”之外调用的函数有关,但为什么要这样做(最好概述一个示例):
function myClass ()
{
var self = this;
//...
this.myArray = [];
this.myFunc = function () { alert(self.myArray.length); };
}
我在 JavaScript 中看到过很多这样的事情,我记得找出原因,但我不记得答案了。
我猜这与范围和在“类”之外调用的函数有关,但为什么要这样做(最好概述一个示例):
function myClass ()
{
var self = this;
//...
this.myArray = [];
this.myFunc = function () { alert(self.myArray.length); };
}
为了将变量锁定为闭包的一部分。
例如:
MyClass.prototype.doStuff = function(){
this.foundItems = [];
var self = this;
this.myString.replace(/.../,function(){
// `this` is actually the `window` inside this callback
// so we need to use `self` to invoke another method on our instance object
self.foundItems.push( self.doOtherStuff() );
});
};
如果您以预期的方式调用该方法,则您编写的特定示例不需要闭包:
function Foo(){
this.array = [];
this.myFunc = function(){
return this.array;
}
}
var foo = new Foo;
foo.myFunc(); // []
但是,可以像这样“破坏”它:
var f2 = foo.myFunc;
f2(); // undefined, since `this` was the window
另一方面,使用闭包的代码对这种愚蠢行为是安全的。
“this”指的是当前的“对象”。在谈论 javascript 时,权力在于“this”表达式是根据上下文评估的,例如,如果一个方法在另一个对象上下文中执行,“this”值将分别改变。
如果您在另一个函数中创建一个函数,this
则内部函数将设置为全局窗口对象。如果您创建一个保存 的值的变量this
,例如
var that = this;
然后您可以使用that
在内部函数中引用外部函数。
除了其他用户发布的一些答案之外,创建变量集允许您在不访问对象的情况下重用变量。
类似于做类似的事情:
var myElement = document.getElementById('someElement');
然后在需要时访问 myElement 而不是 document.getElementById 多次。
设置 that = this 或 self = this 使您可以在任何地方访问“that”或“self”,并防止重新加载某些对象。
我不认为一个人真的想这样做:
替代:
function MyClass() {
this.myArray = [];
this.myFunc = this.myFunc.bind(this); //The "blueprint" in the prototype is not affected, the instance gets its own bound version.
//This means the one in prototype can be inherited or used generically anywhere else as well
}
MyClass.prototype = {
myFunc: function() { //My func is neatly listed in the prototype and can use `this` normally
alert(this.myArray.length);
},
constructor: MyClass
};
var myObj = new MyClass();
document.addEventListener( "click", myObj.myFunc ); //Will now work as you "expect" it to work
一些缺点:
.bind
构造函数中的所有调用的样板文件,尽管可以通过像这样的助手来缓解_.bindAll