这是 Web 应用程序开发中的常见问题,尤其是当您尝试使用实例方法作为事件处理程序时。
通常,当你调用类似的东西时
instance.method(foo);
功能method
被称为,与this
指向instance
and foo
作为唯一的参数。这就是大多数人期望此代码的行为方式。
然而,instance.method
(没有调用)只是对函数的引用。如果你这样做:
const bar = instance.method;
bar(foo);
你会看到不同的行为。在这种情况下,bar
被称为this
没有指向任何东西并且foo
作为唯一的参数。这是因为该函数不再绑定到instance
就像你打电话时的样子instance.method(foo)
;
这正是您致电时发生的情况
this.container.addEventListener("mousedown", this.dragStart, false);
您传入对函数的引用this.dragStart
指向,但与您的班级的连接丢失了。
有很多方法可以解决这个问题。它们都有效地执行相同的操作,即将事件处理程序绑定到类的实例:
箭头函数表达式你可以使用箭头函数表达式 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions绑定值this
到你的班级:
constructor() {
this.container.addEventListener("mousedown", (e) => this.dragStart(e), false);
this.container.addEventListener("mouseup", (e) => this.dragEnd(e), false);
this.container.addEventListener("mousemove", (e) => this.drag(e), false);
}
绑定方法您还可以使用bind method https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind显式绑定this
到函数参考
constructor() {
this.container.addEventListener("mousedown", this.dragStart.bind(this), false);
this.container.addEventListener("mouseup", this.dragEnd.bind(this), false);
this.container.addEventListener("mousemove", this.drag.bind(this), false);
}
ES6方法定义您还可以更改定义类方法的方式,以便将函数绑定到类的实例:
class DragEvents {
/* ... */
drag = () => { /* ... */ }
dragStart = () => { /* ... */ }
dragEnd = () => { /* ... */ }
}//End Class