为什么实例变量未定义?

时间:2013-02-11 16:28:05

标签: javascript

我不明白一件事:

 var comein = document.getElementById("comein");

 var enter = new Expand({ elem : comein });

function Expand (options) {
    this._elem = options.elem;
    console.log(this._elem); // i have a div element    
}

Expand.prototype = {        
    check : function () {

        var comInClassName = this._elem.className; // i have an error: this._elem is undefined

        if (comInClassName == "open"){
          this.close();
        }
        if (comInClassName == "close"){
          this.open();
        }
    }
}
log_in.addEventListener("click",  enter.check, false);

为什么我在原型方法中遇到错误,如果在Expand中我有一个普通的元素?感谢

1 个答案:

答案 0 :(得分:6)

这完全取决于您调用 check的方式。如果你这样称呼它:

enter.check();

....然后在调用中,this将引用enter对象,它将具有_elem属性。另一方面,如果你把它设置为这样调用:

enter._elem.addEventListener('click', enter.check, false);

...然后在通话中(当事件发生时),this引用enter,而是引用this._elem,等等它没有_elem属性。

这是因为在JavaScript(现在)中,函数调用中的this完全由函数的调用方式定义,而不是定义函数的位置。如果将其作为从对象检索函数引用的表达式的一部分来调用它:

enter.check();

...然后this引用您从中获取函数引用的对象。但是,如果您单独调用它,就像上面的addEventListener调用一样,它就不会。

如果您使用的是启用ECMAScript5的环境(或者如果您有适当的ES5垫片),可以使用Function#bind来解决这个问题:

enter._elem.addEventListener('click', enter.check.bind(enter), false);

bind返回一个函数,该函数在调用时将转向并使用给定的this值(在我们的示例中为enter)调用基础函数。

更多内容(在我的博客上):