解决此范围界定问题的最佳方法是什么?
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。我怎么做到这一点?
答案 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,你也可以使用这种方法,我知道它与你在问题中发布的不同,但我仍然可以选择。
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();
})