網站搜尋

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

如果你想用 TypeScript 的方式捕捉 this,那就是透過箭頭函數。引用 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)將不會被使用。

了解更多:《理解 TypeScript 中的 this》(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));
    }
}