"这个"在es6类方法中

And*_*ing 28 javascript class this ecmascript-6

出于某种原因,我在es6课程中为"this"获得了奇怪的价值......

'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);
Run Code Online (Sandbox Code Playgroud)
<button id="thing">Click me</button>
Run Code Online (Sandbox Code Playgroud)

题:

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

更重要的是,如果我不能使用"this"来执行此操作,如何从其"点击方法"中引用Clickers的count属性?

jfr*_*d00 32

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

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


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

this.elem.addEventListener('click', this.click.bind(this));
Run Code Online (Sandbox Code Playgroud)

说明:

Javascript中的所有函数调用都this根据函数的调用方式设置新值.有关基本规则的更多信息,请参阅此说明.

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

this.elem.addEventListener('click', this.click);
Run Code Online (Sandbox Code Playgroud)

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

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

最重要的是,.addEventListener()它专门用于设置它this调用回调时的值(指向this创建事件的元素).

因此,您可以使用.bind()如上所示强制在this调用方法时使用适当的值.


作为参考,您可能会发现在Javascript中为函数调用设置的六种方法的这种描述this很有用.


其他选择

我发现.bind()这是定义它的最清晰的方法,但你也可以使用本地匿名函数:

var self = this;
this.elem.addEventListener('click', function() {
    self.click();
});
Run Code Online (Sandbox Code Playgroud)

或者在ES6中,箭头功能:

this.elem.addEventListener('click', () => this.click());
Run Code Online (Sandbox Code Playgroud)

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