在回调函数中引用我的对象时,我遇到了普通的旧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;
    }
};

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

var x = new foo('test');

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

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

有帮助吗?

解决方案

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

问题在于以下几行:

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

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

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

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

由于在创建闭包时为变量self指定了 this ,因此闭包函数将在以后调用时记住自变量的值。

解决此问题的另一种方法是创建一个实用程序函数(并避免使用变量来绑定 this ):

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

更新后的代码如下:

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

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

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#这样的委托,因此无法传递方法和应该应用的对象作为回调。

在回调中调用方法的唯一方法是在回调函数中自己调用它。因为JavaScript函数是闭包,所以它们能够访问在它们创建的范围内声明的变量。

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

对问题的一个很好的解释(我在理解到目前为止所描述的解决方案时遇到了问题)是可在此处获取

我写了这个插件......

我认为它会很有用

jquery.callback

这是JS最令人困惑的一点:'this'变量意味着最本地的对象......但是函数也是对象,所以'this'指向那里。还有其他微妙的观点,但我不记得它们。

我通常会避免使用'this',只需定义一个本地'me'变量并使用它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top