1 回答

TA贡献1757条经验 获得超7个赞
要删除事件监听器,您需要保留对要删除的函数的引用:
class Sample {
constructor() {
this.value = 'something';
// I've changed it from "let func" to "this.func" so we retain a reference
// I also moved it from addClickListener to the constructor so that we
// don't overwrite our reference when binding more elements to the
// same function
this.func = function(e) {
//what I want to be able to do:
this.doThing(e); // NOTE: You have another bug here. See comments
}
}
addClickListener(e) { // e is a dom element
// Replaced "func" with "this.func"
e.addEventListener('click', this.func, false);
}
removeClickListener(e) {
// Removed the new (unused) function
// Replaced "func" with "this.func"
e.removeEventListener('click', this.func, false);
}
doThing(p) {
//code
}
}
请注意,我在评论中说:“注意:您在这里还有另一个错误”
调用事件侦听器时,上下文(this变量)将更改为发出事件的元素。因此this.doThing将尝试调用doThing该元素e!
还要注意的是e元素(传递给参数addClickListener是不一样的e事件(参数传递给this.func)
要修复此错误,您需要存储对该类的引用,并在函数定义中使用该引用:
constructor() {
this.value = 'something';
let self = this;
this.func = function(e) {
self.doThing(e);
}
}
这里self将不会被覆盖一样this的意志,所以我们可以放心地使用它来引用的类实例
更好的解决方案
当我重新阅读问题时,我意识到您的函数实际上只是在调用另一个函数。因此,为什么不将要最终运行的功能传递给它addEventListener呢?
class Sample {
constructor() {
this.value = 'something';
}
addClickListener(e) {
e.addEventListener('click', this.doThing, false);
}
removeClickListener(e) {
e.removeEventListener('click', this.doThing, false);
}
doThing(p) {
//code
}
}
请注意,这仍然存在this被调用事件的元素替换的问题,因此doThing您不能说this.doOtherThing调用第二类方法。如果您希望这样做,则需要使用JavaScript的方法创建一个bound方法,.bind()如下所示:
class Sample {
constructor() {
this.value = 'something';
this.boundMethod = this.doThing.bind(this);
}
addClickListener(e) {
e.addEventListener('click', this.boundMethod, false);
}
removeClickListener(e) {
e.removeEventListener('click', this.boundMethod, false);
}
doThing(p) {
//code
this.doOtherThing(p);
//more code
}
doOtherThing(p) {
//code
}
}
另一种选择
正如@evolutionxbox指出的那样,您也可以使用箭头功能。此解决方案如下所示:
class Sample {
constructor() {
this.value = 'something';
this.boundMethod = p => { this.doThing(p); };
}
addClickListener(e) {
e.addEventListener('click', this.boundMethod, false);
}
removeClickListener(e) {
e.removeEventListener('click', this.boundMethod, false);
}
doThing(p) {
//code
this.doOtherThing(p);
//more code
}
doOtherThing(p) {
//code
}
}
起作用的原因是箭头函数是绑定方法的简写:
x => x + 1;
// Is functionally equivalent to:
(function(x) {
return x + 1;
}).bind(this);
许多人没有意识到箭头函数包含隐式bind,并且对于90%的用例而言,这并不重要(例如array.map(x => x + 1),不在乎的值this),但是在类中,该简写实际上具有价值,因此成为在JavaScript类中使用箭头函数以避免覆盖this变量的相当普遍的模式。
添加回答
举报