TypeScript學習筆記(三)
本篇將介紹在TypeScript裡如何定義和使用方法。
一、方法標準宣告和使用
1 // 方法宣告 2 function func(x: number, y: number): number { 3 return x + y; 4 }
在TypeScript裡,方法宣告可以明確定義每一個引數的型別,和返回值的型別。在編譯時,編譯器會檢查方法體的返回值型別是否符合定義的型別,同時在呼叫的時候也會檢查傳入的引數型別是否符合定義的型別,引數個數是否符合定義的個數。
1 let result1 = func(1, 2); // 正確的呼叫方式。 2 let result2 = func_lambda(1, 2, 3); //錯誤的呼叫方式。引數個數多餘定義。 3 let result3 = func_lambda(1); // 錯誤的呼叫方式。引數個數少於定義。 4 let result4 = func_lambda('1', '2'); // 錯誤的呼叫方式。引數型別不符合定義。
另外,方法宣告也支援使用Lambda表示式。
1 // lambda表示式宣告 2 let func_lambda: (x: number, y: number) => number = function (x, y) { return x + y };
二、預設引數宣告
在某些情況下,方法呼叫只需要傳入部分引數。TypeScript也支援預設引數的宣告方式。
1 // 預設引數定義 2 let showName = function (firstName: string, lastName?: string): string { 3 if (lastName) { 4 return firstName + ' ' + lastName; 5 } else { 6 return firstName; 7 } 8 }; 9 10 let wholeName1 = showName('星辰', 'Lee'); 11 let wholeName2 = showName('星辰');
通過在引數名稱後面加上?,標識該引數是預設的,呼叫時如果對應引數位置不傳入,對應引數位置則為undefined。
三、預設值引數宣告
在某些情況下,方法呼叫時某些引數在不傳入時,預設使用方法定義的值。TypeScript同樣支援預設值引數的宣告方式。
1 // 預設值引數定義 2 let showName2 = function (firstName: string, lastName = 'Lee'): string { 3 return firstName + ' ' + lastName; 4 }; 5 6 let wholeName3 = showName2('星辰');
通過在引數名稱後加上=號並賦值,標識該引數具有預設值。呼叫時如果對應引數位置不傳入或者傳入undefined,則取預設值,否則取對應位置傳入的值。
四、多引數宣告
像其他強型別語言一樣,TypeScript在定義方法的時候,也支援不明數量的多引數傳入。
1 // 多引數定義 2 let restParamsFunc = function (param1: string, ...restParams: string[]): string { 3 return param1 + ' ' + restParams.join(' '); 4 }; 5 6 let resParamsFuncResult = restParamsFunc('a', 'b', 'c');
通過在參入名稱前加上...(三個小數點),標識對應位置的引數可以傳入多個。因為引數型別已明確定義,所以傳入的多個引數的型別必須與定義保持一致,否則編譯時將提示錯誤。
五、其他型別引數宣告
物件型別:
1 // 物件型別引數 2 let jsonParamFunc = function (x: { p1: string }): string { 3 return x.p1; 4 }; 5 6 let jsonParamFuncResult1 = jsonParamFunc({ p1: 'a' }); // 賦值型別正確 7 let jsonParamFuncResult2 = jsonParamFunc({ p1: 'a', p2: 'b' }); // 賦值型別錯誤,引數屬性比定義的多。 8 let jsonParamFuncResult3 = jsonParamFunc({ p3: 'c' }); // 複製型別錯誤,引數屬性名不匹配。 9 let params = { p1: 'a', p2: 'b' }; 10 let jsonParamFuncResult4 = jsonParamFunc(params); // 用變數代替直接複製,編譯器檢查通過。
上面的例子裡,引數型別被定義為一個擁有屬性“p1”的json物件。在方法呼叫時,傳入的引數將嚴格符合引數型別的定義,引數物件的屬性多餘或者少於定義將提示錯誤,屬性名稱與定義不一致也將提示錯誤。
但是,如果傳入的是一個變數,變數的屬性只要能滿足定義的型別屬性即可。
方法型別:
1 // 方法型別引數 2 let funcParamFunc = function (func: (x: string, y: string) => string): string { 3 let _x = 'a'; 4 let _y = 'b'; 5 return func(_x, _y); 6 }; 7 8 let funParamFuncResult = funcParamFunc(function (x, y) { return x + y });
方法引數型別可定義為一個固定結構的方法,該方法就成為了一個回撥方法。
六、方法過載
TypeScript也支援方法過載。
1 // 方法過載 2 function overloadFunc(x: { p1: string }): string; 3 function overloadFunc(x: number): number; 4 function overloadFunc(x): any { 5 if (typeof x == 'object') { 6 return x.p1; 7 } 8 9 if (typeof x == 'number') { 10 return x; 11 } 12 } 13 14 let overloadFuncResult1 = overloadFunc({ p1: 'a' }); 15 let overloadFuncResult2 = overloadFunc(1);
在上面的例子裡,連續聲明瞭擁有同一個名稱的三個方法:
前兩個方法只有方法定義,沒有方法體。它們定義了過載方法的個數和表現形式。
最後一個方法的引數沒有定義型別,返回值定義為any,同時有方法體。它定義了過載方法的具體實現。
最後,將以上程式碼編譯過後的JavaScript程式碼展示出來,可以進行對比。
1 // 方法宣告 2 function func(x, y) { 3 return x + y; 4 } 5 var result1 = func(1, 2); // 正確的呼叫方式。 6 var result2 = func_lambda(1, 2, 3); // 錯誤的呼叫方式。引數個數多餘定義。 7 var result3 = func_lambda(1); // 錯誤的呼叫方式。引數個數少於定義。 8 var result4 = func_lambda('1', '2'); // 錯誤的呼叫方式。引數型別不符合定義。 9 // lambda表示式宣告 10 var func_lambda = function (x, y) { return x + y; }; 11 // 預設引數定義 12 var showName = function (firstName, lastName) { 13 if (lastName) { 14 return firstName + ' ' + lastName; 15 } 16 else { 17 return firstName; 18 } 19 }; 20 var wholeName1 = showName('星辰', 'Lee'); 21 var wholeName2 = showName('星辰'); 22 // 預設值引數定義 23 var showName2 = function (firstName, lastName) { 24 if (lastName === void 0) { lastName = 'Lee'; } 25 return firstName + ' ' + lastName; 26 }; 27 var wholeName3 = showName2('星辰'); 28 // 多引數定義 29 var restParamsFunc = function (param1) { 30 var restParams = []; 31 for (var _i = 1; _i < arguments.length; _i++) { 32 restParams[_i - 1] = arguments[_i]; 33 } 34 return param1 + ' ' + restParams.join(' '); 35 }; 36 var resParamsFuncResult = restParamsFunc('a', 'b', 'c'); 37 // 物件型別引數 38 var jsonParamFunc = function (x) { 39 return x.p1; 40 }; 41 var jsonParamFuncResult1 = jsonParamFunc({ p1: 'a' }); // 賦值型別正確 42 var jsonParamFuncResult2 = jsonParamFunc({ p1: 'a', p2: 'b' }); // 賦值型別錯誤,引數屬性比定義的多。 43 var jsonParamFuncResult3 = jsonParamFunc({ p3: 'c' }); // 複製型別錯誤,引數屬性名不匹配。 44 var params = { p1: 'a', p2: 'b' }; 45 var jsonParamFuncResult4 = jsonParamFunc(params); // 用變數代替直接複製,編譯器檢查通過。 46 // 方法型別引數 47 var funcParamFunc = function (func) { 48 var _x = 'a'; 49 var _y = 'b'; 50 return func(_x, _y); 51 }; 52 var funParamFuncResult = funcParamFunc(function (x, y) { return x + y; }); 53 function overloadFunc(x) { 54 if (typeof x == 'object') { 55 return x.p1; 56 } 57 if (typeof x == 'number') { 58 return x; 59 } 60 } 61 var overloadFuncResult1 = overloadFunc({ p1: 'a' }); 62 var overloadFuncResult2 = overloadFunc(1);