TypeScript 函數

函數是一組一起執行一個任務的語句。

您可以把代碼劃分到不同的函數中。如何劃分代碼到不同的函數中是由您來決定的,但在邏輯上,劃分通常是根據每個函數執行一個特定的任務來進行的。

函數聲明告訴編譯器函數的名稱、返回類型和參數。函數定義提供了函數的實際主體。


函數定義

函數就是包裹在花括弧中的代碼塊,前面使用了關鍵字 function:

語法格式如下所示:

function function_name()
{
    // 執行代碼
}

實例

TypeScript

function () { // 函數定義 console.log("調用函數") }

調用函數

函數只有通過調用才可以執行函數內的代碼。

語法格式如下所示:

function_name()

實例

TypeScript

function test() { // 函數定義 console.log("調用函數") } test() // 調用函數

函數返回值

有時,我們會希望函數將執行的結果返回到調用它的地方。

通過使用 return 語句就可以實現。

在使用 return 語句時,函數會停止執行,並返回指定的值。

語法格式如下所示:

function function_name():return_type {
    // 語句
    return value;
}
  • return_type 是返回值的類型。

  • return 關鍵字後跟著要返回的結果。

  • 一個函數只能有一個 return 語句。

  • 返回值的類型需要與函數定義的返回類型(return_type)一致。

實例

TypeScript

// 函數定義 function greet():string { // 返回一個字串 return "Hello World" } function caller() { var msg = greet() // 調用 greet() 函數 console.log(msg) } // 調用函數 caller()
  • 實例中定義了函數 greet(),返回值的類型為 string。

  • greet() 函數通過 return 語句返回給調用它的地方,即變數 msg,之後輸出該返回值。。

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

// 函數定義 function greet() { return "Hello World"; } function caller() { var msg = greet(); // 調用 greet() 函數 console.log(msg); } // 調用函數 caller();

帶參數函數

在調用函數時,您可以向其傳遞值,這些值被稱為參數。

這些參數可以在函數中使用。

您可以向函數發送多個參數,每個參數使用逗號 , 分隔:

語法格式如下所示:

function func_name( param1 [:datatype], param2 [:datatype]) {
}
  • param1、param2 為參數名。

  • datatype 為參數類型。

實例

TypeScript

function add(x: number, y: number): number { return x + y; } console.log(add(1,2))
  • 實例中定義了函數 add(),返回值的類型為 number。

  • add() 函數中定義了兩個 number 類型的參數,函數內將兩個參數相加並返回。

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

function add(x, y) { return x + y; } console.log(add(1, 2));

輸出結果為:

3

可選參數和默認參數

可選參數

在 TypeScript 函數裏,如果我們定義了參數,則我們必須傳入這些參數,除非將這些參數設置為可選,可選參數使用問號標識 ?。

實例

TypeScript

function buildName(firstName: string, lastName: string) { return firstName + " " + lastName; } let result1 = buildName("Bob"); // 錯誤,缺少參數 let result2 = buildName("Bob", "Adams", "Sr."); // 錯誤,參數太多了 let result3 = buildName("Bob", "Adams"); // 正確

以下實例,我麼將 lastName 設置為可選參數:

TypeScript

function buildName(firstName: string, lastName?: string) { if (lastName) return firstName + " " + lastName; else return firstName; } let result1 = buildName("Bob"); // 正確 let result2 = buildName("Bob", "Adams", "Sr."); // 錯誤,參數太多了 let result3 = buildName("Bob", "Adams"); // 正確

可選參數必須跟在必需參數後面。 如果上例我們想讓 firstName 是可選的,lastName 必選,那麼就要調整它們的位置,把 firstName 放在後面。

如果都是可選參數就沒關係。

默認參數

我們也可以設置參數的默認值,這樣在調用函數的時候,如果不傳入該參數的值,則使用默認參數,語法格式為:

function function_name(param1[:type],param2[:type] = default_value) {
}
注意:參數不能同時設置為可選和默認。

實例

以下實例函數的參數 rate 設置了默認值為 0.50,調用該函數時如果未傳入參數則使用該默認值:

TypeScript

function calculate_discount(price:number,rate:number = 0.50) { var discount = price * rate; console.log("計算結果: ",discount); } calculate_discount(1000) calculate_discount(1000,0.30)

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

function calculate_discount(price, rate) { if (rate === void 0) { rate = 0.50; } var discount = price * rate; console.log("計算結果: ", discount); } calculate_discount(1000); calculate_discount(1000, 0.30);

輸出結果為:

計算結果:  500
計算結果:  300

剩餘參數

有一種情況,我們不知道要向函數傳入多少個參數,這時候我們就可以使用剩餘參數來定義。

剩餘參數語法允許我們將一個不確定數量的參數作為一個數組傳入。

TypeScript

function buildName(firstName: string, ...restOfName: string[]) { return firstName + " " + restOfName.join(" "); } let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

函數的最後一個命名參數 restOfName 以 ... 為首碼,它將成為一個由剩餘參數組成的數組,索引值從0(包括)到 restOfName.length(不包括)。

TypeScript

function addNumbers(...nums:number[]) { var i; var sum:number = 0; for(i = 0;i<nums.length;i++) { sum = sum + nums[i]; } console.log("和為:",sum) } addNumbers(1,2,3) addNumbers(10,10,10,10,10)

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

function addNumbers() { var nums = []; for (var _i = 0; _i < arguments.length; _i++) { nums[_i] = arguments[_i]; } var i; var sum = 0; for (i = 0; i < nums.length; i++) { sum = sum + nums[i]; } console.log("和為:", sum); } addNumbers(1, 2, 3); addNumbers(10, 10, 10, 10, 10);

輸出結果為:

和為: 6
和為: 50

匿名函數

匿名函數是一個沒有函數名的函數。

匿名函數在程式運行時動態聲明,除了沒有函數名外,其他的與標準函數一樣。

我們可以將匿名函數賦值給一個變數,這種運算式就成為函數運算式。

語法格式如下:

var res = function( [arguments] ) { ... }

實例

不帶參數匿名函數:

TypeScript

var msg = function() { return "hello world"; } console.log(msg())

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var msg = function () { return "hello world"; }; console.log(msg());

輸出結果為:

hello world

帶參數匿名函數:

TypeScript

var res = function(a:number,b:number) { return a*b; }; console.log(res(12,2))

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var res = function (a, b) { return a * b; }; console.log(res(12, 2));

輸出結果為:

24

匿名函數自調用

匿名函數自調用在函數後使用 () 即可:

TypeScript

(function () { var x = "Hello!!"; console.log(x) })()

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

(function () { var x = "Hello!!"; console.log(x) })()

輸出結果為:

Hello!!

構造函數

TypeScript 也支持使用 JavaScript 內置的構造函數 Function() 來定義函數:

語法格式如下:

var res = new Function( [arguments] ) { ... })

實例

TypeScript

var myFunction = new Function("a", "b", "return a * b"); var x = myFunction(4, 3); console.log(x);

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var myFunction = new Function("a", "b", "return a * b"); var x = myFunction(4, 3); console.log(x);

輸出結果為:

12

遞歸函數

遞歸函數即在函數內調用函數本身。

舉個例子:
從前有座山,山裏有座廟,廟裏有個老和尚,正在給小和尚講故事呢!故事是什麼呢?"從前有座山,山裏有座廟,廟裏有個老和尚,正在給小和尚講故事呢!故事是什麼呢?'從前有座山,山裏有座廟,廟裏有個老和尚,正在給小和尚講故事呢!故事是什麼呢?……'"

實例

TypeScript

function factorial(number) { if (number <= 0) { // 停止執行 return 1; } else { return (number * factorial(number - 1)); // 調用自身 } }; console.log(factorial(6)); // 輸出 720

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

function factorial(number) { if (number <= 0) { // 停止執行 return 1; } else { return (number * factorial(number - 1)); // 調用自身 } } ; console.log(factorial(6)); // 輸出 720

輸出結果為:

720

Lambda 函數

Lambda 函數也稱之為箭頭函數。

箭頭函數運算式的語法比函數運算式更短。

函數只有一行語句:

( [param1, parma2,…param n] )=>statement;

實例

以下實例聲明了 lambda 運算式函數,函數返回兩個數的和:

TypeScript

var foo = (x:number)=>10 + x console.log(foo(100)) //輸出結果為 110

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var foo = function (x) { return 10 + x; }; console.log(foo(100)); //輸出結果為 110

輸出結果為:

110

函數是一個語句塊:

( [param1, parma2,…param n] )=> {

    // 代碼塊

}

實例

以下實例聲明了 lambda 運算式函數,函數返回兩個數的和:

TypeScript

var foo = (x:number)=> { x = 10 + x console.log(x) } foo(100)

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var foo = function (x) { x = 10 + x; console.log(x); }; foo(100);

輸出結果為:

110
我們可以不指定函數的參數類型,通過函數內來推斷參數類型:

TypeScript

var func = (x)=> { if(typeof x=="number") { console.log(x+" 是一個數字") } else if(typeof x=="string") { console.log(x+" 是一個字串") } } func(12) func("Tom")

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var func = function (x) { if (typeof x == "number") { console.log(x + " 是一個數字"); } else if (typeof x == "string") { console.log(x + " 是一個字串"); } }; func(12); func("Tom");

輸出結果為:

12 是一個數字

Tom 是一個字串

單個參數 () 是可選的:

TypeScript

var display = x => { console.log("輸出為 "+x) } display(12)

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var display = function (x) { console.log("輸出為 " + x); }; display(12);

輸出結果為:

輸出為 12

無參數時可以設置空括弧:

TypeScript

var disp =()=> { console.log("Function invoked"); } disp();

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

var disp = function () { console.log("調用函數"); }; disp();

輸出結果為:

調用函數

函數重載

重載是方法名字相同,而參數不同,返回類型可以相同也可以不同。

每個重載的方法(或者構造函數)都必須有一個獨一無二的參數類型列表。

參數類型不同:

function disp(string):void;
function disp(number):void;

參數數量不同:

function disp(n1:number):void;
function disp(x:number,y:number):void;

參數類型順序不同:

function disp(n1:number,s1:string):void;
function disp(s:string,n:number):void;

如果參數類型不同,則參數類型應設置為 any

參數數量不同你可以將不同的參數設置為可選。

實例

以下實例定義了參數類型與參數數量不同:

TypeScript

function disp(s1:string):void; function disp(n1:number,s1:string):void; function disp(x:any,y?:any):void { console.log(x); console.log(y); } disp("abc") disp(1,"xyz");

編譯以上代碼,得到以下 JavaScript 代碼:

JavaScript

function disp(x, y) { console.log(x); console.log(y); } disp("abc"); disp(1, "xyz");

輸出結果為:

abc
undefined
1
xyz