我对Javascript类非常陌生,为了了解为什么我的属性在所有方法中都变得不确定,我被困了几天。
我试图将this复制到一个类中,但是没有成功,因为每次调用一个方法时,我的属性都是未定义的。
我在stackoverflow上找不到类似的问题,但是如果有一个问题,请链接我,因为我可能没有搜索正确的问题。
<div class="row" style="height: 800px;">
<div class="col" id="container">
<div class="card" style="width: 300px; border-top: solid 20px black;" id="dragcard">
<div class="card-body">
<p>Text</p>
</div>
</div>
</div>
</div>
class DragEvents {
dragCard = document.querySelector("#dragcard");
container = document.querySelector("#container");
currentX = 0;
currentY = 0;
initialX;
initialY;
constructor() {
this.container.addEventListener("mousedown", this.dragStart, false);
this.container.addEventListener("mouseup", this.dragEnd, false);
this.container.addEventListener("mousemove", this.drag, false);
console.log(this.currentX);//works, but I need this to work in my methods.
}
drag() {
console.log("Drag");//fires
console.log(this.currentX);//undefined
console.log(this.currentY);//undefined
console.log(this.initialX);//undefined
console.log(this.initialY);//undefined
}
dragStart() {
console.log("DragStart");//fires
}
dragEnd() {
console.log("DragEnd");//fires
}
}//End Class
var DragEvent = new DragEvents();
这是webapp开发中的常见问题,尤其是当您尝试将实例方法用作事件处理程序时。
通常,当您打电话给类似的人时>
instance.method(foo);
将调用
method
函数,其中this
指向instance
,而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
所指向的函数的引用,但是与您的类的连接丢失。
有多种解决方法。它们都有效地执行了相同的操作,即将事件处理程序绑定到您的类的实例:
箭头函数表达式
您可以使用arrow function expressions将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将bind
明确绑定到函数引用您还可以更改定义类方法的方式,以便将函数绑定到类的实例:this
ES6方法定义
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);
}