En este script es6, el evento de clic no funciona porque el método sayHello se llama con this.elm ( <div> ) como this .
¿Cómo asociar un evento a un método sin perder el alcance?
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); } }Este es un problema general de JS, pero el núcleo es que
this.elm.addEventListener('click', this.sayHello);no es diferente de
var fn = this.sayHello; this.elm.addEventListener('click', fn); Está pasando una función como controlador de eventos, pero no se ha asegurado de que cuando this llame a fn , se establecerá en el valor deseado. La forma más fácil de hacer esto en ES5 sería
this.elm.addEventListener('click', this.sayHello.bind(this));o en ES6, usando una función de flecha:
this.elm.addEventListener('click', evt => this.sayHello(evt)); Sin embargo, tenga en cuenta que ambas soluciones romperán su lógica (ya ligeramente rota) al kill porque
this.elm.removeEventListener('click', /* what? */);Ya no tiene ninguna referencia a la función que adjuntó, por lo que no tiene forma de eliminar el controlador de eventos.
Yo sugeriría dos opciones:
// 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);o
// 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);