对象文字jquery事件范围

Object literal jquery event scoping

本文关键字:范围 事件 jquery 文字 对象      更新时间:2023-09-26

解决这个作用域问题的最佳方法是什么?

NAMESPACE.myObject = {
  foo: 'foo',
  init: function() {
    $('.myBtn').on('click', this.myMethod);
  },
  myMethod: function() {
    console.log($(this), foo);
  }
};
NAMESPACE.myObject.init();

console.log的结果应该是被点击的jQuery对象和myObject的属性foo。我该如何做到这一点?

基本上你不能有一个以上的this,所以需要围绕它工作。

作为一般规则,创建一个作用域变量(在下面的示例中为THIS)来保存您希望在任何其他作用域中保留/访问的作用域。

你需要在调用myMethod时保留this,虽然,在点击处理程序中,所以你不能只传递myMethod,因为它失去了myObject实例。

NAMESPACE.myObject = {
  this.foo: 'foo',
  init: function() {
    var THIS = this;
    $('.myBtn').on('click', function(){
        // "this" here is the button clicked
        // "THIS" is still the myObject instance
        THIS.myMethod(this);
    });
  },
  myMethod: function(element) {
    // "this" here is myObject
    // The clicked element was passed as parameter "element" instead
    console.log($(element), this.foo);
  }
};
NAMESPACE.myObject.init();

我希望我已经把这个解释得够清楚了:)

正如jfriend00指出的那样,你也可以使用bind来创建一个具有this作用域的函数调用(非常可爱),但这在IE8或更早的版本上不起作用。

您可以这样使用.bind():

NAMESPACE.myObject = {
  foo: 'foo',
  init: function() {
    $('.myBtn').on('click', this.myMethod.bind(this));
  },
  myMethod: function() {
    console.log($(this), foo);
  }
};
NAMESPACE.myObject.init();

或者,对于旧版本的IE,因为你已经有了jQuery,你可以使用jQuery的$.proxy():

NAMESPACE.myObject = {
  foo: 'foo',
  init: function() {
    $('.myBtn').on('click', $.proxy(this.myMethod, this));
  },
  myMethod: function() {
    console.log($(this), foo);
  }
};
NAMESPACE.myObject.init();

当您将this.myMethod传递给事件侦听器时,它将失去与this的绑定(正如您已经注意到的),因为事件侦听器不会保存该引用或使用它调用方法。保持绑定的一种方法是使用.bind()(需要IE9或早期版本的IE的polyfill)。

既然我看到你标记了jQuery,你也可以使用这种方法,我知道它与你在问题中发布的不同,但我仍然是一个选项。

工作示例

var NAMESPACE = NAMESPACE || {};  
$(function() {
    "use strict"
    $.extend(NAMESPACE, true, {
        getMyObject: function() {
             function myObject() {
                var self = this;
                self.foo = 'foo';
                self.init = function() {
                                $('.myBtn').click(self.myMethod); 
                };
                self.myMethod = function() {
                                console.log($(this), self.foo);
                };
            }
            return new myObject(); 
        }
    }); 
    var myObject = NAMESPACE.getMyObject();
    myObject.init();
})