在javascript原型事件处理程序中保留“this”引用
在对象原型中存储的事件处理程序中,保留this
JavaScript引用的正确方法是什么? 我想远离创build像'_this'或'that'的临时variables,我不能使用像jQuery这样的框架。 我看到很多人谈论使用“绑定”function,但不知道如何在我的情况下实现它。
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()
是迄今为止最干净的解决scheme:
this.bar.onclick = this.ClickEvent.bind(this);
顺便说一下, this
是常被称为惯例。
查看关于bind
的MDN文档: https : //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
使用这个function,你可以改变范围( this
是什么):
Example.prototype.SetEvent = function(){ this.bar.onclick = this.ClickEvent.bind(this); };
但请注意,这是EMCA的新增function,因此可能在所有用户代理中都不受支持。 在上面链接的MDN文件中有一个pollyfill。
bind
的问题是只支持IE9 + 。
该函数可以用es5-shim
,但与本地实现不完全相同:
- 警告:绑定函数有一个原型属性。
- 警告:绑定的函数不要太费劲,以防止操纵它们的
arguments
和caller
属性。- 警告:绑定的函数在
call
没有检查,并apply
以避免作为构造函数执行。
另一种select可以是jQuery.proxy
:
$(elem).on('click', $.proxy(eventHandler, this));
如果以后要删除事件处理程序,这更有帮助,因为当函数通过proxy
方法时,jQuery会生成一个新的guid值,然后将该guid应用于核心函数以及结果代理函数您可以使用原始函数引用来解除已经代理的事件处理程序callback:
$(elem).off('click', eventHandler);
其他解决scheme:使用ES6引入的“箭头function”。 那些有特殊性的不改变的上下文, this
IE指的是什么。 这里是一个例子:
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 }
箭头function规格@ MDN
编辑
要小心它。 如果你使用它的客户端,并且你不能确定JS解释器的function,请注意,旧的浏览器将不会识别箭头函数( 请参阅CanIUse统计信息 )。 只有当你知道什么会运行它(仅适用于最近的浏览器和NodeJS应用程序)