无法访问事件中的对象属性

fen*_*itk -1 javascript scope

我有这样的代码:

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

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

Obj.el.addEventListener('click', Obj.doSomething);
Run Code Online (Sandbox Code Playgroud)

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

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

T.J*_*der 5

在JavaScript(不像类似的语法大多数其他语言),this完全由定义如何调用一个函数,而不是在那里的定义.this在函数中调用事件处理程序的方式不会引用您的对象.

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

  1. 如果您的目标是支持ES5的浏览器或包含ES5"垫片",请使用Function#bind:

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

    var Obj = {
      el : document.getElementById,
    
      doSomething : function(){ this.el.property = "value" }
    };
    
    Obj.el.addEventListener('click', function(event) {
        return Obj.doSomething(event);
    });
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    
    Run Code Online (Sandbox Code Playgroud)

    仅当对象在其定义的范围内是一次性时才有效(对于您的Obj示例,这是正确的).如果你唯一的参考是this(例如,你没有Obj),你就不能这样做,并且会想要前两个选项中的一个.

更多:


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

el : document.getElementById,
Run Code Online (Sandbox Code Playgroud)

...这意味着el现在指向该功能 getElementById.这可能不是你的意思.大概你el想要引用你通过 检索的DOM元素getElementById,例如:

el : document.getElementById("someIdValue"),
Run Code Online (Sandbox Code Playgroud)

更多这里.