保存';这';javascript原型事件处理程序中的引用
在对象原型中存储的事件处理程序中保存保存';这';javascript原型事件处理程序中的引用,javascript,oop,event-handling,this,Javascript,Oop,Event Handling,This,在对象原型中存储的事件处理程序中保存此javascript引用的正确方法是什么?我不想创建像“this”或“that”这样的临时变量,也不能使用像jQuery这样的框架。我看到很多人谈论使用“bind”函数,但不确定如何在我给定的场景中实现它 var Example = function(foo,bar){ this.foo = foo; this.bar = bar; }; Example.prototype.SetEvent = function(){ this.ba
此javascript引用的正确方法是什么?我不想创建像“this”或“that”这样的临时变量,也不能使用像jQuery这样的框架。我看到很多人谈论使用“bind”函数,但不确定如何在我给定的场景中实现它
var Example = function(foo,bar){
this.foo = foo;
this.bar = bar;
};
Example.prototype.SetEvent = function(){
this.bar.onclick = this.ClickEvent;
};
Example.prototype.ClickEvent = function(){
console.log(this.foo); // logs undefined because 'this' is really 'this.bar'
};
我发现bind()
是迄今为止最干净的解决方案:
this.bar.onclick = this.ClickEvent.bind(this);
顺便说一句,另一个通常被称为,
。查看bind
上的MDN文档:
使用此功能,您可以更改范围(此
是什么):
但是,请注意,这是EMCA的新添加,因此可能并非所有用户代理都支持。在上面链接的MDN文档中有一个pollyfill可用。问题在于
该函数可以多填充,但与本机实现不完全相同:
- 警告:绑定函数具有原型属性
- 警告:绑定函数不会试图阻止您操作它们的
参数
和调用者
属性
- 警告:绑定函数在
call
和apply
中没有检查,以避免作为构造函数执行
另一种选择是:
如果您希望稍后删除事件处理程序,这将更有帮助,因为当函数通过该方法时,jQuery会生成一个新的guid值,然后将该guid应用于核心函数以及生成的代理函数,因此,您可以使用原始函数引用解除已代理的事件处理程序回调的绑定:
$(elem).off('click', eventHandler);
其他解决方案:使用ES6引入的“箭头函数”。它们具有不改变上下文的特殊性,即这
指向的内容。以下是一个例子:
function Foo(){
myeventemitter.addEventListener("mousedown", (()=>{
return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
})());
}
Foo.prototype.myinstancefunction = function(event){
// Handle event in the context of your Object
}
编辑
小心点。如果您在客户端使用它,并且无法确定JS解释器的功能,请注意,旧浏览器无法识别箭头函数()。只有当您知道将运行什么时才使用此方法(仅限最新浏览器和NodeJS应用程序)我讨厌创建一个称为“that”(la Crockford)的引用。我更喜欢“instance”(一个la Stefanov)或“me”(一个la ExtJS)实际上,我讨厌创建this
引用,不管它们是如何命名的。但我同意,这并不是最好的命名。我使用“self”,但最近发现它与WebWorkers中的顶级属性名称冲突。并不是说你不能有相同的名字,但它确实混淆了事情。此外,我发现名称“that”与“this”完全相反@GeorgeJempty这只是个人偏好这当然在旧IE(8及以上版本)中不起作用。bind()
与$.proxy
一样完全跨浏览器。它基本上是.bind()
的非标准版本。如果您列出的注意事项实际上是一个问题,那么$.proxy
将不会更好。更不用说这个问题很清楚,他不能使用jQuery。@我建议使用$.proxy
(或类似的实现),因为它是一个松散的连接,这对OO事件处理非常有帮助。但谢谢你,我会更新我的答案,因为正如你所说,polyfilled.bind()
与$.proxy
一样完全跨浏览器。
$(elem).off('click', eventHandler);
function Foo(){
myeventemitter.addEventListener("mousedown", (()=>{
return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
})());
}
Foo.prototype.myinstancefunction = function(event){
// Handle event in the context of your Object
}