JavaScriptcallback范围

我在callback函数中引用我的对象时遇到了一些普通的旧JavaScript(无框架)的麻烦。

function foo(id) { this.dom = document.getElementById(id); this.bar = 5; var self = this; this.dom.addEventListener("click", self.onclick, false); } foo.prototype = { onclick : function() { this.bar = 7; } }; 

现在,当我创build一个新的对象(在DOM加载后,用span#test)

 var x = new foo('test'); 

onclick函数中的'this'指向了span#test而不是foo对象。

如何在onclick函数中获得对foo对象的引用?

(提取了一些在其他答案中隐藏在注释中的解释)

问题在于以下行:

 this.dom.addEventListener("click", self.onclick, false); 

在这里,你传递一个函数对象来作为callback。 当事件触发时,该函数被调用,但现在它与任何对象(this)都没有关联。

该问题可以通过将函数(使用它的对象引用)封装在闭包中来解决,如下所示:

 this.dom.addEventListener( "click", function(event) {self.onclick(event)}, false); 

由于variablesself是在创build闭包时分配的,因此闭包函数将在以后调用selfvariables时记住自variables的值。

解决这个问题的另一种方法是创build一个效用函数(并避免使用variables来绑定这个函数):

 function bind(scope, fn) { return function () { fn.apply(scope, arguments); }; } 

更新后的代码将如下所示:

 this.dom.addEventListener("click", bind(this, this.onclick), false); 

Function.prototype.bind是ECMAScript 5的一部分,并提供相同的function。 所以你可以这样做:

 this.dom.addEventListener("click", this.onclick.bind(this), false); 

对于尚不支持ES5的浏览器, MDN提供以下垫片 :

 if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 internal IsCallable function throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () {}, fBound = function () { return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; } 
 this.dom.addEventListener("click", function(event) { self.onclick(event) }, false); 

对于寻找解决这个问题的jQuery用户,你应该使用jQuery.proxy

解释是, self.onclick并不意味着你在JavaScript中的含义。 它实际上意味着对象self的原型中的onclick函数(不以任何方式引用self本身)。

JavaScript只有函数而没有像C#这样的委托,所以不可能传递一个方法和它应该作为callback的对象。

在callback中调用方法的唯一方法是在callback函数中自己调用它。 由于JavaScript函数是闭包,因此它们可以访问在创build它们的范围中声明的variables。

 var obj = ...; function callback(){ return obj.method() }; something.bind(callback); 

对这个问题的一个很好的解释(到目前为止我对理解解决scheme有困难) 可以在这里find 。

我写了这个插件…

我认为这将是有益的

jquery.callback

这是JS最令人困惑的一点:“this”variables意味着最本地的对象…但函数也是对象,所以“this”指向那里。 还有其他一些细微之处,但我不记得全部。

我通常避免使用“this”,只是定义一个本地的“我”variables,并使用它。