Javascript:Class 属性在拖动事件期间变得未定义
Javascript: Class Properties becoming undefined during Drag Events
我对 Javascript 中的 classes 很陌生,我已经被困了几天试图理解为什么我的属性在我的所有方法中都变得未定义...
我试图将 this 复制到 class,但没有成功,因为每次调用方法时我的属性都未定义。
我在 Whosebug 上找不到类似的问题,但如果有的话请 link 我,因为我可能没有搜索正确的问题。
<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.method(foo)
;
时那样绑定到 instance
这正是您调用
时发生的情况
this.container.addEventListener("mousedown", this.dragStart, false);
您传递了对 this.dragStart
指向的函数的引用,但是与您的 class 的连接丢失了。
有很多方法可以解决这个问题。他们都有效地做同样的事情,即将事件处理程序绑定到您的 class:
的实例
箭头函数表达式
您可以使用 arrow function expressions 将 this
的值绑定到您的 class:
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 将 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 方法的方式,以便将函数绑定到 class:
的实例
class DragEvents {
/* ... */
drag = () => { /* ... */ }
dragStart = () => { /* ... */ }
dragEnd = () => { /* ... */ }
}//End Class
我对 Javascript 中的 classes 很陌生,我已经被困了几天试图理解为什么我的属性在我的所有方法中都变得未定义...
我试图将 this 复制到 class,但没有成功,因为每次调用方法时我的属性都未定义。
我在 Whosebug 上找不到类似的问题,但如果有的话请 link 我,因为我可能没有搜索正确的问题。
<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.method(foo)
;
instance
这正是您调用
时发生的情况this.container.addEventListener("mousedown", this.dragStart, false);
您传递了对 this.dragStart
指向的函数的引用,但是与您的 class 的连接丢失了。
有很多方法可以解决这个问题。他们都有效地做同样的事情,即将事件处理程序绑定到您的 class:
的实例箭头函数表达式
您可以使用 arrow function expressions 将 this
的值绑定到您的 class:
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 将 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 方法的方式,以便将函数绑定到 class:
的实例class DragEvents {
/* ... */
drag = () => { /* ... */ }
dragStart = () => { /* ... */ }
dragEnd = () => { /* ... */ }
}//End Class