对象文字jquery事件范围

时间:2014-05-09 14:13:12

标签: javascript jquery

解决此范围界定问题的最佳方法是什么?

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。我怎么做到这一点?

3 个答案:

答案 0 :(得分:3)

基本上你不能拥有多个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或更早版本。

答案 1 :(得分:2)

您可以像这样使用.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()(对于早期版本的IE,需要IE9或polyfill)。

答案 2 :(得分:1)

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

working example

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();
})