1. 程式人生 > >TypeScript學習筆記(三)

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);
複製程式碼