ค้นหาเว็บไซต์

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));
    }
}

บทความที่เกี่ยวข้อง