考虑以下示例:
class Test {
constructor() {
this.x = 42;
}
someMethod() {
console.log(this.x);
}
}
testBtn.x = -42;
var TestInstance = new Test()
testBtn.addEventListener('click', TestInstance.someMethod);
<button id="testBtn" type="button">Click me</button>
单击按钮会将-42
登录到控制台。
我知道我可以通过将TestInstance
显式绑定到事件处理程序引用来解决此问题:
class Test {
constructor() {
this.x = 42;
}
someMethod() {
console.log(this.x);
}
}
testBtn.x = -42;
var TestInstance = new Test()
testBtn.addEventListener('click', TestInstance.someMethod.bind(TestInstance));
<button id="testBtn" type="button">Click me</button>
缺点是我无法再删除该事件侦听器。
我知道这也可以解决:
class Test {
constructor() {
this.x = 42;
this.someMethod = this._someMethod.bind(this);
}
_someMethod() {
console.log(this.x);
testBtn.removeEventListener('click', this.someMethod);
}
}
testBtn.x = -42;
var TestInstance = new Test()
testBtn.addEventListener('click', TestInstance.someMethod);
<button id="testBtn" type="button">Click me</button>
但这基本上意味着要在需要this
指向实例的每个方法上公开类API,我必须在构造函数中创建该方法的绑定版本。
这是否是预期的工作方式,还是我错过了其他不同且希望更好的方法?
编辑:因此,我将继续进行此操作,直到公共类字段语法提案已通过提案状态:
class Test {
constructor() {
this.x = 42;
const boundMethodNames = ['someMethod'];
boundMethodNames.forEach(method => this[method] = this[method].bind(this));
}
someMethod() {
console.log(this.x);
testBtn.removeEventListener('click', this.someMethod);
}
}
testBtn.x = -42;
var TestInstance = new Test();
testBtn.addEventListener('click', TestInstance.someMethod);
<button id="testBtn" type="button">Click me</button>