代码之家  ›  专栏  ›  技术社区  ›  n1313

如何在jquery中创建合适的闭包?

  •  3
  • n1313  · 技术社区  · 15 年前

    这是我的代码示例:

    var bar = function() {
    
      this.baz = function() {
        this.input = $('.input');
        this.input.bind("keydown keyup focus blur change", this.foo);
      }
    
      this.foo = function(event){
        console.log(this);
      }
    
    }
    

    点击我的输入 input 显然,在控制台中。我怎样才能得到 bar 作为 this 相反?

    4 回复  |  直到 8 年前
        1
  •  5
  •   Christian C. Salvadó    15 年前

    那是因为当你 bind 事件,事件处理程序函数通过触发事件的dom元素的上下文调用, this 关键字表示dom元素。

    要获得“bar”,您应该存储对外部闭包的引用:

    var bar = function() {
      var self = this;
    
      this.baz = function() {
        this.input = $('.input');
        this.input.bind("keydown keyup focus blur change", this.foo);
      }
    
      this.foo = function(event){
        console.log(this); // the input
        console.log(self); // the bar scope
      }
    };
    

    注: 如果调用bar函数时不使用 new 运算符, 将是窗口对象并且 baz foo 将成为全局变量,请小心!

    不过,我认为您的代码可以简化:

    var bar = {
      baz: function() {
        var input = $('.input');
        input.bind("keydown keyup focus blur change", this.foo);
      },
    
      foo: function(event){
        console.log(this); // the input
        console.log(bar); // reference to the bar object
      }
    };
    
        2
  •  1
  •   Tomas Kirda    15 年前

    要在比赛场地上获得酒吧,请执行以下操作:

    bar = function() {
    
    var me = this;
    
    this.baz = function() {
        this.input = $('.input');
        this.input.bind("keydown keyup focus blur change", this.foo);
    }
    
    this.foo = function(event){
        // me, would be your bar object.
        console.log(me);
    }
    
    }
    
        3
  •  1
  •   Matt Good    15 年前

    在JavaScript中使用实例方法作为回调时,这是一个普遍的问题。我使用此函数创建一个闭包来调用绑定到正确实例的方法:

    function bound_method(instance, method) {
      return function() {
        return method.apply(instance, arguments);
      };
    }
    

    然后,您可以使用此作为回调来代替this.foo:

    bound_method(this, this.foo)
    

    与其他一些建议不同,这允许您将方法放在原型上,而不是在构造函数中创建它们。这样,您就只有一个实现的共享副本,而不是为BAR的每个新实例重新创建这些函数。

    var bar = function() {};
    $.extend(bar, {
      baz: function() {
        this.input = $('.input');
        this.input.bind("keydown keyup focus blur change",
                        bound_method(this, this.foo));
      },
    
      foo: function(event) {
        console.log(this);
      }
    });
    
        4
  •  0
  •   Santosh Gokak    15 年前

    给你,这是如何得到“这个”的一个例子

    <html>
    <head></head>
    <script  type="text/javascript" src="jquery-1.3.2.min.js"></script>
    
    <script>
     var  bar = function() {
    
    this.baz = function() {
        this.input = $('.input');
        this.input.bind("keydown keyup focus blur change", this.foo);
    }
    
    this.foo = function(event){
        console.log(this);
    }
    
    }
    
    </script>
    <body>
    <input class="input">
    <button onclick="new bar().baz()">Click</button>
    </body>
    </html>
    

    这是因为函数baz是用bar.so的实例调用的,所以bar是在“new bar()”上下文中执行的,而不是窗口对象。

    如果您使用的是Firebug(看起来是这样的),那么在单击控制台选项卡中的单击之前和之后,您可以在输入文本控件中键入内容时跟踪日志记录。