[英]Object literal jquery event scoping
What is the best way to solve this scoping problem? 解决此范围界定问题的最佳方法是什么?
NAMESPACE.myObject = {
foo: 'foo',
init: function() {
$('.myBtn').on('click', this.myMethod);
},
myMethod: function() {
console.log($(this), foo);
}
};
NAMESPACE.myObject.init();
The result of the console.log should be the jQuery object that was clicked and the propertie foo of myObject. console.log的结果应该是单击的jQuery对象和myObject的属性foo。 How would I achieve this? 我将如何实现?
Basically you can't have more than one this
, so need to work around it. 基本上你不能有一个以上的this
,所以需要解决它。
As a general rule, create a scoped variable ( THIS
in the example below) to hold the scope you want to retain/access from inside any other scope. 通常,创建一个范围变量(在下面的示例中为THIS
)以保存您要从其他范围内保留/访问的范围。
You need to retain the this
on the call to the myMethod though, inside the click handler, so you can't just pass myMethod
as it loses the myObject
instance. 不过,您需要在单击处理程序内的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();
I hope I explained this clearly enough :) 我希望我解释这显然不够:)
As jfriend00 points out, you can also use bind
to basically create a function call with this
scope on-the-fly (very cute), but that does not work on IE8 or older. 正如jfriend00所指出的,您还可以使用bind
来动态地(在this
范围内)动态创建一个函数调用(非常可爱),但这不适用于IE8或更旧的版本。
You can use .bind()
like this: 您可以像这样使用.bind()
:
NAMESPACE.myObject = {
foo: 'foo',
init: function() {
$('.myBtn').on('click', this.myMethod.bind(this));
},
myMethod: function() {
console.log($(this), foo);
}
};
NAMESPACE.myObject.init();
Or, for older versions of IE, since you already have jQuery you can use jQuery's $.proxy()
: 或者,对于较旧版本的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();
When you pass this.myMethod
to the event listener, it loses its binding to this
(as you've noticed) because the event listener doesn't save that reference or call the method with it. 当您将this.myMethod
传递给事件侦听器时,它会失去this
绑定(如您所注意到的),因为事件侦听器不会保存该引用或调用该方法。 One way to keep that binding is to use .bind()
(requires IE9 or a polyfill for earlier versions of IE). 保持该绑定的一种方法是使用.bind()
(对于早期版本的IE,需要IE9或polyfill)。
Since I see you tagged jQuery, you can also use this approach, I know it is different from what you posted in the question, but I still an option. 由于我看到您标记了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();
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.