-1

我有这样的代码:

var Obj = {
  el : document.getElementById("elementId"),

  doSomething : function(){ this.el.property = "value" }
};

Obj.el.addEventListener('click', Obj.doSomething);

this.el 但是当点击事件被触发时元素是未定义的?是什么导致这种情况发生?

注意:我不知道如何在这个编辑器的代码中换行,这就是为什么它在一行中。

4

1 回答 1

5

在 JavaScript 中(与大多数其他具有相似语法的语言不同),this完全由函数的调用方式定义,而不是在哪里定义。在您的函数中调用事件处理程序的方式this并不引用您的对象。

您可以通过三种方式更正它:

  1. 如果您的目标是支持 ES5的浏览器或包含 ES5 “shim”,请使用Function#bind

    var Obj = {
      el : document.getElementById,
    
      doSomething : function(){ this.el.property = "value" }
    };
    
    Obj.el.addEventListener('click', Obj.doSomething.bind(Obj));
    
  2. 否则,使用闭包

    var Obj = {
      el : document.getElementById,
    
      doSomething : function(){ this.el.property = "value" }
    };
    
    Obj.el.addEventListener('click', function(event) {
        return Obj.doSomething(event);
    });
    
  3. 正如 RobG 在评论中指出的那样,因为您只有一个 Obj对象(而不是具有构造函数或根据需要创建多个对象的东西),您可以只使用其变量 ( Obj) 来引用该对象,而不是this

    var Obj = {
      el : document.getElementById,
    
      // Obj instead of this ---v
      doSomething : function(){ Obj.el.property = "value" }
    };
    
    Obj.el.addEventListener('click', Obj.doSomething);
    

    仅当对象在其定义的范围内是一次性的时才有效(对于您的Obj示例来说是这样)。如果您对它的唯一引用是this(例如,您没有Obj),那么您不能这样做并且需要前两个选项之一。

更多的:


但是请注意,您的el财产是可疑的。您已将其定义为

el : document.getElementById,

...这意味着el现在指向函数 getElementById。这可能不是你的本意。大概您的意思el是指您通过 getElementById检索到的 DOM 元素,例如:

el : document.getElementById("someIdValue"),

更多在这里

于 2012-04-15T22:11:28.260 回答