【问题标题】:JavaScript "this" references wrong object [duplicate]JavaScript“this”引用了错误的对象[重复]
【发布时间】:2012-02-28 17:04:31
【问题描述】:

嗯,this 并没有真正引用 错误 对象,但我不知道如何引用正确的对象。

function someObj() {
   this.someMethod1 = function() {
      var elementBtn = document.getElementById('myBtn');
      elementBtn.onclick = function() { 
         this.someMethod2(); //I want this.someMethod2() to be called
         //...but it tries to call elementBtn.someMethod2() i believe.
      };
   };
   this.someMethod2 = function() {
      alert('OK');
   };
}

所以当我的myBtn 被点击时,我希望someObj.someMethod2() 运行。我希望它是 someObj,而不是 任何其他 someObj。但是怎么做?!

【问题讨论】:

    标签: javascript onclick javascript-objects dom-events


    【解决方案1】:

    您可能需要进行如下调整:

    function someObj() {
        var that = this;
    
        this.someMethod1 = function() {
            var elementBtn = document.getElementById('myBtn');
            elementBtn.onclick = function() { 
                that.someMethod2();
            };
        };
        this.someMethod2 = function() {
           alert('OK');
        };
    }
    

    “that”捕获了您所追求的范围。

    【讨论】:

    • 非常感谢,这确实解决了问题,但它似乎是一种令人讨厌的解决方案?!有没有其他方法可以做到这一点?
    • 嗯,你可以返回一个对象中的方法(方法 this 指向该对象),然后绑定该函数的“this”。有关绑定的更多信息,developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
    【解决方案2】:

    function keyword changes scope。一种解决方案是保留对您要使用的“this”的引用。

    尝试以下方法:

    function someObj() {
       var self = this;
       this.someMethod1 = function() {
          var elementBtn = document.getElementById('myBtn');
          elementBtn.onclick = function() { 
             self.someMethod2(); //NOTE self
          };
       };
       this.someMethod2 = function() {
          alert('OK');
       };
    }
    

    【讨论】:

    • 约定说我们应该使用that来保存this
    • @GrzegorzGierlik 我读到了很好的部分,可能应该提到这一点,但我相信self 更具描述性。
    • 这取决于你的背景:),但你是对的——对于许多开发人员来说,自己可能更具描述性。
    【解决方案3】:

    你可以使用coffee脚本,它有一个粗箭头(用于onclick函数)来处理这种事情,并编译成格式良好的javascript。通过使用粗箭头,coffee 脚本确保在回调函数中使用与定义函数相同的范围。

    play with code here

    咖啡脚本

    someObj = () ->
       @someMethod1 = () ->
          elementBtn = document.getElementById 'myBtn'
          elementBtn.onclick = () => 
             @someMethod2()
       this.someMethod2 = () ->
          alert 'OK'
    

    JavaScript

    var someObj;
    var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
    someObj = function() {
      this.someMethod1 = function() {
        var elementBtn;
        elementBtn = document.getElementById('myBtn');
        return elementBtn.onclick = __bind(function() {
          return this.someMethod2();
        }, this);
      };
      return this.someMethod2 = function() {
        return alert('OK');
      };
    };
    

    【讨论】:

    • 但我不想使用 CoffeeScript。
    • @torazaburo 没关系,您不必使用咖啡脚本。但是,即使不直接使用它,您仍然可以从其设计中的模式中学习(顺便说一句,这对 es6 产生了重大影响)。在这种情况下,在生成的 javascript 中显示了在咖啡脚本具有粗箭头语法的被调用函数中保留当前上下文的模式。 Coffee-script 这样做的方法是一种通用的解决方案,并且经过了尝试和测试。通过检查输出的 javascript,可以理解原始问题的答案——即使你讨厌咖啡脚本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-22
    相关资源
    最近更新 更多