【问题标题】:Overwritten "this" variable problem or how to call a member function?覆盖“this”变量问题或如何调用成员函数?
【发布时间】:2010-10-18 18:10:23
【问题描述】:

我有这个类,我使用 jQuery 和 Prototype 的组合:

var MyClass = Class.create({
    initElements: function(sumEl) {
       this.sumEl = sumEl;
       sumEl.keyup(this.updateSumHandler);
    },

    updateSumHandler: function(event) {
       // Throws error here: "this.updateSum is not a function"
       this.updateSum();
    },

    updateSum: function() {
       // does something here
    }
});

毕竟我怎么能打电话给this.updateSum()?

【问题讨论】:

    标签: javascript jquery oop event-handling prototypejs


    【解决方案1】:

    你需要使用闭包。

     initElements: function(sumEl) {
            this.sumEl = sumEl;
            var ref = this;
            sumEl.keyup( function(){ref.updateSumHandler();});
     },
    

    【讨论】:

      【解决方案2】:

      完全未经测试的建议:

      sumEl.keyup(this.updateSumHandler.bind(this));
      

      .bind() 返回一个新函数,其中bind 的第一个参数作为函数的this 上下文为您关闭。 也可以关闭参数,查看documentation。

      对我来说,Function.bind() 是用 JavaScript 编写的最好的函数 :)

      【讨论】:

      • +1。 Function.bind 将成为 JavaScript 未来版本中的标准语言功能。
      【解决方案3】:

      DOMEvent 处理程序通常使用它们注册为上下文/“this”的元素来调用。这也是 jQuery 所做的。

      对您来说最简单的选择是使用 jQuery 处理事件数据的能力

      var MyClass = Class.create({
       initElements: function(sumEl) {
              this.sumEl = sumEl;
              sumEl.bind("keyup", this, this.updateSumHandler);
       },
      
       updateSumHandler: function(event) {
          // event.data is the initial this
      
          // call updateSum with correct context
          event.data.updateSum.call(event.data);
       },
      
       updateSum: function() {
              // does something here
       }
      });
      

      另一种可能性是使用闭包在构造函数中定义updateHandler

      var MyClass = Class.create({
       initElements: function(sumEl) {
              this.sumEl = sumEl;
      
              // save this as that so we can access it from the anonymous function
              var that = this;
              sumEl.keyup(function()
              {
                 that.updateSum();
              });
       },
      
       updateSum: function() {
              // does something here
       }
      });
      

      这是其他答案之一尝试做的工作示例。它之所以有效,是因为匿名函数总是可以访问周围函数中的变量——但它只有在函数真正定义在以“that”作为局部变量的函数中时才有效。

      【讨论】:

        【解决方案4】:

        这是您需要在initElements函数中使用的著名Javascript习语:

        var that = this;
        

        稍后在您的处理程序中只需引用that 而不是this:

        var MyClass = Class.create({
            initElements: function(sumEl) {
                this.sumEl = sumEl;
                var that = this;
                sumEl.keyup(this.updateSumHandler);
            },
            updateSumHandler: function(event) {
                that.updateSum();
            },
            updateSum: function() {
                // does something here
            }
        });
        

        talk by Stuart Langridge 在 Fronteers 2008 会议上的 Javascript 闭包 中对此进行了详细介绍。

        【讨论】:

        • 不,为什么?这是一个闭包,所以它应该在 updateSumHandler 的范围内。不过,没有测试该代码。
        猜你喜欢
        • 2022-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-31
        相关资源
        最近更新 更多