typescript中this報錯的解決
typescript中this報錯
export class AppComponent { title = 'myapp'; count=1; clickme=function(){ this.count++; }
在上述代碼中
使用this報錯: 'this' implicitly has type 'any' because it does not have a type annotation.
function處報錯: An outer value of 'this' is shadowed by this container
出錯原因
ts 提供類似C# 和 java的靜態(tài)類型(強類型), 在全局和命名空間的全局里面 直接聲明一個函數(shù)要用到 function 關(guān)鍵字(就是js的function關(guān)鍵字),
而在類(class)里面卻不能使用function來聲明方法。
這其中是this的指向問題。
改成這樣就可以了
export class AppComponent { title = 'myapp'; count=1; clickme=()=>{ this.count++; } }
typescript中this的使用注意
最近的一個項目,用了 typescript 來寫js腳本,結(jié)果錯誤百出,修復(fù)的同時也讓我總結(jié)了ts 中該怎樣使用this。
ts 提供類似C# 和 java的靜態(tài)類型(強類型), 在全局和命名空間的全局里面 直接聲明一個函數(shù) 要用到 function 關(guān)鍵字(就是js的function關(guān)鍵字),而在類(class)里面卻不能使用function來聲明方法。
讓我們來比較 它與 C# 的不同
? ? public delegate int handle(); ? ? public class Program ? ? { ? ? ? ? public static void Main(string[] args) ? ? ? ? { ? ? ? ? ? ? var t = new Test(); ? ? ? ? ? ? var a = new A(); ? ? ? ? ? ? t.h = a.hander; ? ? ? ? ? ? t.count = t.h(); ? ? ? ? ? ? Console.WriteLine("count is:{0}",t.count);? ? ? ? ? ? ? // output: ? ? ? ? ? ? // count is:1 ? ? ? ? } ? ? } ? ? public class Test ? ? { ? ? ? ? public handle h; ? ? ? ? public int count = 100; ? ? } ? ? public class A ? ? { ? ? ? ? private int count = 0; ? ? ? ? public int hander() ? ? ? ? { ? ? ? ? ? ? this.count +=1; ? ? ? ? ? ? return this.count; ? ? ? ? } ? ? }
這個代碼在class A里面 放了一個方法,并將這個方法作為一個委托 給了 class program 的 h 字段, 最后在 Main 方法里面運個 h委托, 結(jié)果得到了 1 這個結(jié)果(A.count + 1 = 0 + 1 = 1)
讓我們在TypeScript 里面實現(xiàn)相同的功能:
class A { ? ? public count: number = 0; ? ? public hander(): number { ? ? ? ? this.count += 1; ? ? ? ? return this.count; ? ? } } class Test { ? ? public count: number = 100; ? ? public h: () => number; } class Program { ? ? static Main(): void { ? ? ? ? let t = new Test(); ? ? ? ? let a = new A(); ? ? ? ? t.h = a.hander; ? ? ? ? t.count = t.h(); ? ? ? ? console.log(`count is :${t.count}`); ? ? ? ? // output ? ? ? ? // count is :101 ? ? } } Program.Main();// 為了跟C#一致 , 提供的靜態(tài)入口
你會發(fā)現(xiàn),這時候結(jié)果不再是1,而是101, 造成差異的原因是js的 this 指針 , 在 C# 中 this 總是指向當前的類,而 js中的this可以改變, 當 t.h = a.hander 的時候 t.h 中的this 變成了 Test 類。 而在 typescript中,因為當前定義的是一個類,所以其this 總是指向 類,所以TS 直接使用js中的this.
然而 有辦法解決這個問題么? 當然有。 讓我們來改變 class A
class A { ? ? constructor() { ? ? ? ? this.hander = ()=>{ ? ? ? ? ? ? this.count += 1; ? ? ? ? ? ? return this.count; ? ? ? ? } ? ? } ? ? public count: number = 0; ? ? public hander: () => number; }
這樣我們把hander 從類的 方法 變成了 類的變量,更重要的是 我們在 構(gòu)造函數(shù)里面 使用 lamda 表達式 , 使用 lamda表達式 并不會改變this的作用域, 因為當前是一個構(gòu)造函數(shù),所以里面的this指向的是 當前的類,(查看一下生成的js會更容易理解, 函數(shù)里面已經(jīng)沒有了this)
從js的角度, 因為函數(shù)中沒有了this指針,所以也就不會因為 傳遞到其他的地方造成不一致的情況
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue按需加載組件webpack require.ensure的方法
本篇文章主要介紹了vue按需加載組件webpack require.ensure的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12vue中this.$router.push()路由傳值和獲取的兩種常見方法匯總
這篇文章主要介紹了vue中this.$router.push()路由傳值和獲取的兩種常見方法,本文結(jié)合示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-12-12Vue-cli3執(zhí)行serve和build命令時nodejs內(nèi)存溢出問題及解決
這篇文章主要介紹了Vue-cli3執(zhí)行serve和build命令時nodejs內(nèi)存溢出問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01