【问题标题】:How can I avoid using this snippet in Javascript closures?如何避免在 Javascript 闭包中使用此代码段?
【发布时间】:2011-06-14 12:52:25
【问题描述】:

我每天在 Javascript 中使用这个 sn-p 100 次来关闭封闭对象:

Class.prototype.Method = function(arg){
    var Ta = this;
    var e = function(){
        Ta.doSomething(arg);
    };
};

有没有办法避免 Ta 变量仍然引用“外部”(这个词正确吗?)对象?

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    我不知道我会提倡这种优越感,但你可以使用“.bind()”:

    var e = function() {
      this.doSomething(arg);
    }.bind(this);
    

    这确保函数“e”中的this 值始终是周围上下文的this 值。 The .bind() function is available in newer browsers, or via a polyfill like the one on the MDC site.

    我更喜欢保留那些局部变量,尤其是在设置事件处理程序之类的复杂函数中;它有助于阐明代码层之间的关系。

    【讨论】:

      【解决方案2】:

      a) 您可以使用更有意义的变量名继续使用这种方法。使用that 是一种常见的约定——它表明您的变量只是另一个“this”值,但适用于另一个函数范围。

      b) 您可以使用函数绑定实用程序。一些 JavaScript 库自带一个。或者您也可以自己滚动:

      function bind(fn, scope) {
          return function () {
              fn.apply(scope, arguments);
          };
      }
      
      // for your example:
      Class.prototype.Method = function(arg) {
          var e = bind(function() {
              this.doSomething(arg);
          }, this);
      };
      
      // Alternatively, extend the Function prototype (may raise some eyebrows):
      
      Function.prototype.bind = function (scope) {
          var fn = this;
          return function () {
              fn.apply(scope, arguments);
          };
      };
      
      // for your example:
      Class.prototype.Method = function(arg) {
          var e = function() {
              this.doSomething(arg);
          }.bind(this);
      };
      

      更新: 正如@Pointy 所说,bind 实际上是新版本 JavaScript 规范的一部分,已经被现代浏览器采用:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

      【讨论】:

      • 即使我在寻找更简单的东西,我也对 Function 对象的这种扩展感兴趣。感谢发布!
      【解决方案3】:

      我不相信有。我一直都在做同样的事情。

      【讨论】:

        【解决方案4】:

        我使用了一个小型的自制框架来轻松使用原型继承,并且在这个框架中我有大约相同的代码。我认为没有这个是没有办法的。

        现在的问题是:为什么不这样做?你认为这是一种不好的做法,为什么?

        我使用的一段代码:

        function getCallback(obj, methodName) {
            var method = obj[methodName];
        
            function callback() {
                if (obj[methodName] === callback) {
                    return method.apply(obj, arguments);
                }
                return obj[methodName].apply(obj, arguments);
            }
        
            return callback;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-25
          • 2016-08-21
          • 1970-01-01
          • 2011-05-19
          相关资源
          最近更新 更多