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
前面示例中使用的引用.