Javascript ES6 类:在方法上应用“addEventListener”访问“this”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30446622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ES6 Class: access to 'this' with 'addEventListener' applied on method
提问by Yukulélé
In this es6 script, the click event don't works because sayHellomethod is called with this.elm(<div>) as this.
在这个 es6 脚本中,click 事件不起作用,因为sayHello方法是用this.elm( <div>) as调用的this。
how to associate a event to a method without loose the scope?
如何在不失去作用域的情况下将事件与方法相关联?
class player{
constructor (name) {
this.name = name;
this.elm = document.createElement('div');
this.elm.addEventListener('click', this.sayHello);
}
sayHello() {
console.log(this.name + ' say: "hello!"'); // 'undefined say 'hello!"';
}
kill() {
console.log(`RIP ${this.name} :'(`);
this.elm.addClass('dead');
this.elm.removeEventListener('click', this.sayHello);
}
}
回答by loganfsmyth
This is a general JS issue, but the core of it is that
这是一个普遍的 JS 问题,但它的核心是
this.elm.addEventListener('click', this.sayHello);
is no different than
与
var fn = this.sayHello;
this.elm.addEventListener('click', fn);
You are passing a function as the event handler, but have not ensured that when fnis called that thiswill be set to your desired value. The easiest way to do this in ES5 would be
您正在传递一个函数作为事件处理程序,但没有确保何时fn被调用this将被设置为您想要的值。在 ES5 中执行此操作的最简单方法是
this.elm.addEventListener('click', this.sayHello.bind(this));
or in ES6, using an arrow function:
或者在 ES6 中,使用箭头函数:
this.elm.addEventListener('click', evt => this.sayHello(evt));
Note however that both of these solutions will break your (already slightly broken) logic in killbecause
但是请注意,这两种解决方案都会破坏您的(已经稍微损坏的)逻辑,kill因为
this.elm.removeEventListener('click', /* what? */);
You don't have any reference to the function that you attached anymore, so you have no way of removing the event handler.
您不再对附加的函数有任何引用,因此您无法删除事件处理程序。
I'd suggest two options:
我建议两种选择:
// Create a new function that is bound, and give it a new name
// so that the 'this.sayHello()' call still works.
this.boundSayHello = evt => this.sayHello(evt);
this.elm.addEventListener('click', this.boundSayHello);
this.elm.removeEventListener('click', this.boundSayHello);
or
或者
// Bind the function with the same name and use `.bind` instead of the
// arrow function option.
this.sayHello = this.sayHello.bind(this);
this.elm.addEventListener('click', this.sayHello);
this.elm.removeEventListener('click', this.sayHello);

