jquery - Typescript "this" ภายในเมธอดของคลาส
ฉันรู้ว่าสิ่งนี้อาจจะพื้นฐานอย่างเจ็บปวด แต่ฉันกำลังมีความยากลำบากในการทำความเข้าใจมัน
class Main
{
constructor()
{
requestAnimationFrame(this.update); //fine
}
update(): void
{
requestAnimationFrame(this.update); //error, because this is window
}
}
ดูเหมือนว่าฉันจะต้องใช้พร็อกซี ดังนั้นลองพูดว่าใช้ Jquery
class Main
{
constructor()
{
this.updateProxy = $.proxy(this.update, this);
requestAnimationFrame(this.updateProxy); //fine
}
updateProxy: () => void
update(): void
{
requestAnimationFrame(this.updateProxy); //fine
}
}
แต่เนื่องจากมาจากพื้นหลังของ Actionscript 3 ผมก็ไม่ค่อยแน่ใจว่าเกิดอะไรขึ้นที่นี่ ขอโทษครับ ผมไม่แน่ใจว่า Javascript เริ่มตรงไหนและ TypeScript สิ้นสุดตรงไหน
updateProxy: () => void
และนอกจากนี้ ฉันก็ยังไม่มั่นใจว่าฉันกำลังทำสิ่งนี้ถูกต้องหรือไม่ สิ่งสุดท้ายที่ฉันต้องการคือส่วนใหญ่ของคลาสของฉันมีฟังก์ชัน a() ที่ต้องเข้าถึงด้วย aProxy() เพราะฉันรู้สึกว่าฉันกำลังเขียนสิ่งเดียวกันซ้ำอีกครั้ง มันเป็นเรื่องปกติหรือไม่?
คำตอบ #1
หากคุณต้องการให้ this ถูกจับ วิธีการใน TypeScript สำหรับการทำสิ่งนี้คือผ่านฟังก์ชันลูกศร กล่าวโดย Anders:
thisในฟังก์ชันลูกศรมีขอบเขตตามไวยากรณ์
นี่คือวิธีที่ฉันชอบใช้สิ่งนี้ให้เป็นประโยชน์ต่อฉัน:
class test{
// Use arrow functions
func1=(arg:string)=>{
return arg+" yeah" + this.prop;
}
func2=(arg:number)=>{
return arg+10 + this.prop;
}
// some property on this
prop = 10;
}
ดูสิ่งนี้ใน TypeScript Playground
คุณสามารถเห็นได้ว่าใน JavaScript ที่สร้างขึ้น this ถูกจับ นอก การเรียกฟังก์ชัน:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
ดังนั้นค่า this ภายในการเรียกฟังก์ชัน (ซึ่งอาจเป็น window) จะไม่ได้ถูกใช้งาน
เรียนรู้เพิ่มเติม: “ทำความเข้าใจ this ใน TypeScript” (4:05) - YouTube
คำตอบ #2
ถ้าคุณเขียนวิธีของคุณแบบนี้ 'this' จะถูกจัดการตามที่คุณคาดหวัง
class Main
{
constructor()
{
requestAnimationFrame(() => this.update());
}
update(): void
{
requestAnimationFrame(() => this.update());
}
}
อีกทางเลือกหนึ่งคือการผูก 'this' กับการเรียกฟังก์ชัน:
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(this));
}
}
