javascript - es6 类方法内的 "This"

标签 javascript class ecmascript-6 this

出于某种原因,我在 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);
<button id="thing">Click me</button>

问题:

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

更重要的是,如果我不能使用“this”来执行此操作,如何在其“click”方法中引用 Clickers 的 count 属性?

最佳答案

Why is the "this" inside of of the Clickers' click method referring to the dom node rather than ... itself?

因为.addEventListener()的规范是将this指针设置为捕获事件的DOM元素。这就是它的设计原理。

<小时/>

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

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

说明:

Javascript 中的所有函数调用都会根据函数的调用方式设置 this 的新值。请参阅this explanation有关这组基本规则的更多信息。

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

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

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

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

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

因此,您可以使用如上所示的 .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 引用。

关于javascript - es6 类方法内的 "This",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36489579/

相关文章:

javascript - 悬停后如何将内容放入框中?

class - 什么是无状态类?

java - 解决java中的类名冲突

javascript - ./src/components/Main.jsx 中的错误 - Webpack

JavaScript 方法从字符串/数字中删除不区分大小写的重复项

javascript - key 生成将算法作为错误抛出

javascript - 将 PHP 数组传递给 JavaScript 的最佳方法

python - 给定一个 python 2.7.2 类型,我是否可以以编程方式构造一个类实例?

javascript - 基于数组对对象进行排序以生成排序数组

javascript - 将焦点设置到谷歌地图上的对象