由于某些原因,我得到了#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;
为什么&#34;这&#34;在Clickers的内部&#39;点击方法引用dom节点而不是...本身?
更重要的是,我如何参考Clickers&#39;从其内部计算财产。点击方法,如果我不能使用&#34;这个&#34;做到了吗?
答案 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
引用。