确保`this`指向API实例方法中的类的实例

时间:2019-03-06 09:55:06

标签: javascript ecmascript-6 this es6-class

考虑以下示例:

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>

0 个答案:

没有答案