Javascript ES6类:访问';这';与';增补列表器';应用于方法

Javascript ES6类:访问';这';与';增补列表器';应用于方法,javascript,dom,ecmascript-6,dom-events,Javascript,Dom,Ecmascript 6,Dom Events,在这个es6脚本中,click事件不起作用,因为sayHello方法是用this.elm()作为this调用的 如何将一个事件关联到一个方法而不失去作用域 class player{ constructor (name) { this.name = name; this.elm = document.createElement('div'); this.elm.addEventListener('click', this.sayHello); } sayHel

在这个es6脚本中,click事件不起作用,因为
sayHello
方法是用
this.elm
)作为
this
调用的

如何将一个事件关联到一个方法而不失去作用域

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);
  }
}

这是一个一般的JS问题,但其核心是

this.elm.addEventListener('click', this.sayHello);

var fn = this.sayHello;
this.elm.addEventListener('click', fn);
您正在传递一个函数作为事件处理程序,但没有确保在调用
fn
时,
将被设置为所需的值。在ES5中,最简单的方法是

this.elm.addEventListener('click', this.sayHello.bind(this));
或者在ES6中,使用箭头功能:

this.elm.addEventListener('click', evt => this.sayHello(evt));
但是请注意,这两种解决方案都会破坏
kill
中的逻辑(已经稍微中断),因为

this.elm.removeEventListener('click', /* what? */);
您不再对附加的函数有任何引用,因此无法删除事件处理程序

我建议两种选择:

// 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);


谢谢,这就是我所使用的,但是每个对象都需要有一个指向每个绑定函数的对象,这非常好!我喜欢第一种解决方案。首先我尝试了.bind(this),但是当尝试获取此范围内的其他变量时失败了,因为我在一个ES6类中。Ah so
canvas.addEventListener('mousedown',pad_mousedown,false)将是
this.canvas.addEventListener('mousedown',evt=>this.pad\u mousedown(evt),false)
// 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);