在下面的代码中,是否有更好的方法从handleClick()
引用对象实例,而不是将其作为全局引用?
var Widget = function() {
this.property = 'value';
this.bindEvents();
}
Widget.prototype = {
bindEvents: function() {
$('button').on('click', this.handleClick);
},
handleClick: function() {
var self = window.Widget;
console.log(self.property);
}
}
window.Widget = new Widget();
这个question问同样的事情,(未接受的)答案是将回调传递给$.on()
并从那里调用处理程序,将实例作为参数传递给:
bindEvents: function() {
var self = this;
$('button').on('click', function() {
self.handleClick.apply(self);
});
}
这种传递实例的技术是否真正以正确的方式进行,或者除了我展示的两种方式之外还有其他方法吗?
答案 0 :(得分:5)
该对象可以作为eventData传递给on()
,如下所示:
var Widget = function () {
this.property = 'value';
this.bindEvents();
}
Widget.prototype = {
bindEvents: function () {
$('button').on('click', {o: this}, this.handleClick);
},
handleClick: function (e) {
var widgt = e.data.o;
console.log(widgt.property);
}
}
window.Widget = new Widget();
这样可以保持事件处理程序的范围。
答案 1 :(得分:1)
您可以使用bind()
:
bindEvents: function() {
$('button').on('click', function() {
this.handleClick();
}.bind(this));
}
但是当谈到IE时,这只适用于IE> = 9。
在旧版IE中 编辑,你可以使用@Kevin B在评论中建议的jQuery的$.proxy()
:
bindEvents: function() {
$('button').on('click', $.proxy(function() {
this.handleClick();
}, this));
}
答案 2 :(得分:0)
正如@kamituel所说,可以使用bind
:
Widget.prototype = {
bindEvents: function() {
$('button').on('click', this.handleClick.bind(this));
},
handleClick: function() {
console.log(this.property);
}
}
答案 3 :(得分:0)
指定的技术称为闭包,它是常用的。 但是,有时注意不要导致内存泄漏是很重要的。 你可以在这里阅读更多关于闭包的内容:
How do JavaScript closures work?
以及与闭包相关的内存泄漏,这里:
答案 4 :(得分:0)
保存this
的最佳方法是 lambda函数:
$('button').on('click', () => this.handleClick());
或者如果您想保留对事件的引用:
$('button').on('click', (event) => this.handleClick(event));
关于lambda函数的特别之处在于,您不必在(可能不同的)上下文中定义另一个函数。 lambda术语只是一条指令,因此是它在-中定义的对象的一部分-在您的情况下是window.Widget = new Widget()
创建的实例。