JavaScript回调范围 [英] JavaScript Callback Scope

查看:215
本文介绍了JavaScript回调范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm having some trouble with plain old JavaScript (no frameworks) in referencing my object in a callback function.

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加载之后,具有跨度#测试)

Now when I create a new object (after the DOM has loaded, with a span#test)

var x = new foo('test');

在'本'的onclick函数指向跨度#测试里面,而不是Foo对象。

The 'this' inside the onclick function points to the span#test and not the foo object.

我如何获得的onclick函数内到我的Foo对象的引用?

How do I get a reference to my foo object inside the onclick function?

推荐答案

(摘录了一些解释,这是隐藏在对方的回答评论)

问题在于以下行:

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

在这里,你传递给被用作回调函数对象。当事件触发时,函数被调用,但现在它与任何对象没有关联(本)。

Here, you pass a function object to be used as callback. When the event trigger, the function is called but now it has no association with any object (this).

的问题可以通过在一个封闭包裹功能(与它的对象参考)如下来解决:

The problem can be solved by wrapping the function (with it's object reference) in a closure as follows:

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

由于自变量分配的这个的创建关闭时,关闭功能会记得自变量的值时,它被称为在稍后的时间。

Since the variable self was assigned this when the closure was created, the closure function will remember the value of the self variable when it's called at a later time.

要解决这个问题的另一种方法是使一个效用函数(和避免使用变量绑定的这个的):

An alternative way to solve this is to make an utility function (and avoid using variables for binding this):

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

然后更新code看起来像:

The updated code would then look like:

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


<一个href=\"https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind\"><$c$c>Function.prototype.bind是的ECMAScript 5的一部分,并提供相同的功能。所以,你可以这样做:


Function.prototype.bind is part of ECMAScript 5 and provides the same functionality. So you can do:

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

有关不支持ES5还没有浏览器, MDN提供以下垫片

For browsers which do not support ES5 yet, MDN provides the following shim:

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;  
  };  
} 

这篇关于JavaScript回调范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆