在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 ,但与本地实现不完全相同:

  • 警告:绑定函数有一个原型属性。
  • 警告:绑定的函数不要太费劲,以防止操纵它们的argumentscaller属性。
  • 警告:绑定的函数在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应用程序)