ES6 类:在方法上应用“addEventListener”访问“this”

IT技术 javascript dom ecmascript-6 dom-events
2021-01-23 08:35:19

在这个 es6 脚本中,click 事件不起作用,因为sayHello方法是用this.elm( <div>) as调用的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);
  }
}
1个回答

这是一个普遍的 JS 问题,但它的核心是

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

var fn = this.sayHello;
this.elm.addEventListener('click', fn);

您正在传递一个函数作为事件处理程序,但尚未确保何时fn被调用this将设置为您想要的值。在 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 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);
伟大的!我更喜欢第一个解决方案。首先我尝试了 .bind(this) 但是当我尝试在 this 范围内获取其他变量时它失败了,因为我在一个 ES6 类中。
2021-03-16 08:35:19
啊所以canvas.addEventListener('mousedown', pad_mouseDown, false);在 ES6 类样式中将是this.canvas.addEventListener('mousedown', evt=> this.pad_mouseDown(evt), false);
2021-03-30 08:35:19
谢谢,这是我使用的,但每个对象都需要有一个对象指向每个绑定函数所需的回调codepen.io/yukulele/pen/yNVVxV/?editors=001
2021-04-05 08:35:19