"这"在es6类方法中

时间:2016-04-08 00:34:59

标签: javascript class ecmascript-6 this

由于某些原因,我得到了#34;这个"在我的es6班......



'use strict';
class Clicker {
  constructor(element) {
    this.count = 0;
    this.elem = element;
    this.elem.addEventListener('click', this.click);
    
    // logs Clicker { count:0, elem: button#thing} as expected
    console.log(this);
  }

  click() {
    // logs <button id="thing">...</button> as unexpected...
    console.log(this);
    this.count++;
  }
}


var thing = document.getElementById('thing');
var instance = new Clicker(thing);
&#13;
<button id="thing">Click me</button>
&#13;
&#13;
&#13;

问题:

为什么&#34;这&#34;在Clickers的内部&#39;点击方法引用dom节点而不是...本身?

更重要的是,我如何参考Clickers&#39;从其内部计算财产。点击方法,如果我不能使用&#34;这个&#34;做到了吗?

1 个答案:

答案 0 :(得分:26)

  

为什么Clickers的点击方法中的“this”指的是   dom节点而不是......本身?

因为.addEventListener()的规范是将this指针设置为捕获事件的DOM元素。这就是设计工作的方式。

将方法作为回调传递到要覆盖this的值时,可以使用.bind()强制使用this所需的值:

this.elem.addEventListener('click', this.click.bind(this));

<强>解释

Javascript中的所有函数调用根据函数的调用方式设置新值this。有关该基本规则的详细信息,请参阅this explanation

最重要的是,当你这样做时:

this.elem.addEventListener('click', this.click);

您只是获取this.click方法并将该方法单独传递给addEventListener()this的值将完全丢失。就好像你这样做:

var m = this.click;     // m here is just a reference to Clicker.prototype.click
this.elem.addEventListener('click', m);

除此之外,.addEventListener()专门用于在调用回调时设置自己的this值(在创建事件的元素处指向this)。

因此,您可以使用上面显示的.bind()强制在调用方法时强制this的正确值。

作为参考,您可能会发现this description of the six ways that this is set在Javascript中的函数调用很有用。

其他选项

我发现.bind()是最明确的定义方式,但您也可以使用本地匿名函数:

var self = this;
this.elem.addEventListener('click', function() {
    self.click();
});

或在ES6中,箭头功能:

this.elem.addEventListener('click', () => this.click());

箭头函数会自动为您保留this的值,以避免需要前面示例中使用的self引用。