3、你能讀得懂的TypeScript教程之函式
函式同樣是TypeScript的基礎之一。通過函式你可以將重合的功能程式碼塊進行封裝,然後在你需要它的時候呼叫即可。換句話說函式就是具有某一功能的程式碼塊,它的使命是將你臃腫的程式碼變的更加苗條。
首先,咱們先來回顧一下之前在JS中是如何建立函式以及實現呼叫的:
1、函式宣告:
function fn (a,b){ return a + b; }
2、函式表示式:
let fn = function (a,b) { return a + b; }
3、箭頭函式:
var fn = (a,b) => a + b; // 函式呼叫 console.log(fn(1,2))
注:以上建立函式的方式在TypeScript中也是支援的。
一、TypeScript中的函式是有型別的
函式的型別分為引數型別與返回值型別。
1、引數型別:通過在引數後加冒號指定引數型別
函式宣告:
function fn (a:number,b:number){ return a + b; }
函式表示式:
var fn = function (a:number,b:number) { return a + b; }
箭頭函式:
let fn = (a:number,b:number) => a + b;
注意:只有引數型別是匹配的,那麼該引數才是有效的。
fn(1,2);// 正確 // A function whose declared type is neither 'void' nor 'any' must return a value. fn("1",true);// error
如果引數型別不確定,可以將型別設定為 any
:
let fn = (a:any,b:any) => a + b; fn("1",true);
2、返回值型別:顧名思義,用於指定返回值的型別。寫法依然是通過冒號指定返回型別。
函式宣告:
function fn (a:number,b:number) : number { return a + b; }
函式表示式:
let fn = function (a:number,b:number) : number{ return a + b; }
箭頭函式:
var fn = (a:number,b:number) :number => a + b;
返回的型別一定要與你指定的型別匹配,否則編譯是不會通過的,如:
// Type 'string' is not assignable to type 'number'. var fn = (a:number,b:number) :number => a + b + "1";
如果沒有返回值,需要指定型別為void:
var fn = function (a:number,b:number) : void{ console.log(a + b); }
如果你指定了返回型別為void,卻偏偏要返回值,那是在找死,一樣不會編譯通過,如:
//'number' is not assignable to type 'void'. var fn = function (a:number,b:number) : void{ return a + b; }
自然,你指定了非void型別,卻沒有返回值,依然是在找死:
// A function whose declared type is neither 'void' nor 'any' must return a value. var fn = function (a:number,b:number) : number{ console.log(a + b); }
二、完整函式型別
注意:Typescript具有型別推斷機制,也就是說如果我們不指定變數的型別,ts會自行對該值的型別進行推斷。例如以下程式碼會自行推斷為string型別:
let siteName = "http://www.zhangpeiyue.com"; console.log(typeof siteName);// string
在之前的例子當中,通過表示式與箭頭函式建立的函式是可以通過編譯的。我們也只是對等號右側的匿名函式進行了型別定義。而等號左邊的 fn並沒有新增型別,其型別是通過賦值操作自行推斷出來的。
完整寫法:
在函式和返回值型別之間使用( =>
)符號,
let fn: (a: number, b: number) => number = function (a: number, b: number): number { return a + b; };
只要引數型別是匹配的,便是有效的函式型別,與引數名稱是否對應無關,以下也是正確的:
let fn: (num1: number, num2: number) => number = function (a: number, b): number { return a + b; };
三、函式引數都是必須的
在JavaScript中,傳遞的引數是可選的,可傳可不傳,當我們沒有傳參的時候,它的值是undefined。 但是在TypeScript中我們傳遞給一個函式的引數個數必須與函式接收的引數個數一致,型別也需要一致。
function fullName(firstName: string, lastName: string) { return firstName + lastName; } // 張三 console.log(fullName("張","三")); // 傳遞型別不同:error Argument of type '3' is not assignable to parameter of type 'string'. console.log(fullName("張",3)); // 傳遞個數少1:error Expected 2 arguments, but got 1. console.log(fullName("王")); //傳遞個數多1:error Expected 2 arguments, but got 3. console.log(fullName("張","培","躍"));
四、可選引數
在上面的示例當中,我們知道傳遞的引數個數需要與函式接收的個數一致。那麼有沒有辦法實現引數的可先呢?當然有!我們只需要在引數旁新增一個 ?
即可。比如,我們讓last name是可選的:
function fullName(firstName: string, lastName?: string) { return firstName + lastName; } // 張三 console.log(fullName("張","三")); // 王undefined console.log(fullName("王")); //error Expected 1-2 arguments, but got 3. console.log(fullName("張","培","躍"));
五、預設引數
通過上例可知,當可選引數未傳遞時,預設值為 undefined
。如果我們想要指定預設值的話,新增 =
即可
function fullName(firstName: string, lastName: string = "六") { return firstName + lastName; } // 張三 console.log(fullName("張","三")); // 王六 console.log(fullName("王")); //error Expected 1-2 arguments, but got 3. console.log(fullName("張","培","躍"));
六、剩餘引數
如果我們不知道有多少引數傳遞進來怎麼辦呢?
在JS中我們可以通過arguments來接收,而在TS中我們可以通過...(三個小數點)來將剩餘的引數放到一個數組中。比如
function fullName(firstName: string, ...lastName: string[]) { return firstName + lastName.join(""); } // 張三 console.log(fullName("張","三")); // 王六 console.log(fullName("王")); // 張培躍 console.log(fullName("張","培","躍"));
七、方法過載(Overload)
函式過載是指同一個函式,根據傳遞的引數不同,會有不同的表現形式。注意在JS當中是不支援過載的。在TS中是提供了過載功能的,但是這個過載功能和C#或者java等語言的過載相比是不完整的。
TypeScript的函式過載共用一個函式體,也就是說無論宣告多少個同名的函式,它們共同使用同一個函式體,在呼叫時會根據傳遞引數型別的不同,而執行這一個函式體。例如:
function fn(name: string): string; function fn(age: number): number; function fn(nameorage: any): any { if (typeof nameorage == "string") { return "姓名:" + nameorage; } else if (typeof nameorage == "number") { return "年齡:" + nameorage } } // 姓名:張培躍 console.log(fn("張培躍")); // 年齡:18 console.log(fn(18));
共用的函式體:
if (typeof nameorage == "string") { return "姓名:" + nameorage; } else if (typeof nameorage == "number") { return "年齡:" + nameorage }
編譯之後的JS:
function fn(nameorage) { if (typeof nameorage == "string") { return "姓名:" + nameorage; } else if (typeof nameorage == "number") { return "年齡:" + nameorage; } } console.log(fn("張培躍")); console.log(fn(18));
好了,今天的分享就到這裡,一定要多練習哦。
[公眾號回覆“電子書”,送你經典前端電子書籍]
—————END—————
喜歡本文的朋友們,歡迎關注公眾號 張培躍 ,收看更多精彩內容
