TypeScript - 函式



TypeScript 中的函式是可讀、可維護和可重用程式碼的構建塊。函式是一組用於執行特定任務的語句。函式將程式組織成邏輯程式碼塊。一旦定義,就可以呼叫函式來訪問程式碼。這使得程式碼可重用。此外,函式使程式程式碼易於閱讀和維護。

函式宣告告訴編譯器函式的名稱、返回型別和引數。函式定義提供了函式的實際主體。

序號 函式及描述
1. 定義函式

函式定義指定了如何完成特定任務。

2. 呼叫函式

必須呼叫函式才能執行它。

3. 返回函式

函式還可以將值以及控制權返回給呼叫方。

4. 引數化函式

引數是將值傳遞給函式的一種機制。

可選引數

當函式執行不需要強制傳遞引數時,可以使用可選引數。可以透過在引數名稱後附加問號來將引數標記為可選。可選引數應設定為函式中的最後一個引數。宣告帶可選引數的函式的語法如下所示:

function function_name (param1[:type], param2[:type], param3[:type])

示例:可選引數

function disp_details(id:number,name:string,mail_id?:string) { 
   console.log("ID:", id); 
   console.log("Name",name); 
   
   if(mail_id!=undefined)  
   console.log("Email Id",mail_id); 
}
disp_details(123,"John");
disp_details(111,"mary","mary@xyz.com");
  • 上面的示例聲明瞭一個引數化函式。這裡,第三個引數,即 mail_id 是一個可選引數。

  • 如果在函式呼叫期間未傳遞可選引數的值,則引數的值將設定為 undefined。

  • 該函式僅在傳遞了引數值時才打印 mail_id 的值。

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
function disp_details(id, name, mail_id) {
   console.log("ID:", id);
   console.log("Name", name);
	
   if (mail_id != undefined)
      console.log("Email Id", mail_id);
}
disp_details(123, "John");
disp_details(111, "mary", "mary@xyz.com");

以上程式碼將產生以下輸出:

ID:123 
Name John 
ID: 111 
Name  mary 
Email Id mary@xyz.com

剩餘引數

剩餘引數類似於 Java 中的可變引數。剩餘引數不限制您可以傳遞給函式的值的數量。但是,傳遞的值必須全部為同一型別。換句話說,剩餘引數充當同一型別多個引數的佔位符。

要宣告剩餘引數,引數名稱前面要加上三個點。任何非剩餘引數都應位於剩餘引數之前。

示例:剩餘引數

function addNumbers(...nums:number[]) {  
   var i;   
   var sum:number = 0; 
   
   for(i = 0;i<nums.length;i++) { 
      sum = sum + nums[i]; 
   } 
   console.log("sum of the numbers",sum) 
} 
addNumbers(1,2,3) 
addNumbers(10,10,10,10,10)
  • 函式 addNumbers() 宣告接受一個剩餘引數 nums。剩餘引數的資料型別必須設定為陣列。此外,函式最多隻能有一個剩餘引數。

  • 該函式被呼叫兩次,分別傳遞三個和六個值。

  • for 迴圈遍歷傳遞給函式的引數列表並計算它們的總和。

編譯後,它將生成以下 JavaScript 程式碼:

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

以上程式碼的輸出如下:

sum of numbers 6 
sum of numbers 50

預設引數

函式引數也可以分配預設值。但是,此類引數也可以顯式傳遞值。

語法

function function_name(param1[:type],param2[:type] = default_value) { 
}

注意 - 引數不能同時宣告為可選和預設。

示例:預設引數

function calculate_discount(price:number,rate:number = 0.50) { 
   var discount = price * rate; 
   console.log("Discount Amount: ",discount); 
} 
calculate_discount(1000) 
calculate_discount(1000,0.30)

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
function calculate_discount(price, rate) {
   if (rate === void 0) { rate = 0.50; }
   var discount = price * rate;
   console.log("Discount Amount: ", discount);
}
calculate_discount(1000);
calculate_discount(1000, 0.30);

其輸出如下:

Discount amount : 500 
Discount amount : 300
  • 該示例聲明瞭函式 calculate_discount。該函式有兩個引數 - price 和 rate。

  • 引數 rate 的值預設設定為 0.50

  • 程式呼叫該函式,僅向其傳遞引數 price 的值。這裡,rate 的值為 0.50(預設)

  • 呼叫相同的函式,但使用兩個引數。rate 的預設值被覆蓋並設定為顯式傳遞的值。

匿名函式

未繫結到識別符號(函式名)的函式稱為匿名函式。這些函式是在執行時動態宣告的。匿名函式可以接受輸入並返回輸出,就像標準函式一樣。匿名函式在其初始建立後通常不可訪問。

變數可以分配匿名函式。這樣的表示式稱為函式表示式。

語法

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

示例 - 簡單匿名函式

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

編譯後,它將在 JavaScript 中生成相同的程式碼。

它將產生以下輸出:

hello world

示例 - 帶引數的匿名函式

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

匿名函式返回傳遞給它的值的乘積。

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
var res = function (a, b) {
   return a * b;
};
console.log(res(12, 2));

以上程式碼的輸出如下:

24

函式表示式和函式宣告 - 它們是同義詞嗎?

函式表示式和函式宣告不是同義詞。與函式表示式不同,函式宣告由函式名稱繫結。

兩者之間的根本區別在於,函式宣告在執行之前進行解析。另一方面,函式表示式僅在指令碼引擎在執行過程中遇到它時才進行解析。

當 JavaScript 解析器在主程式碼流中看到一個函式時,它會假設函式宣告。當函式作為語句的一部分出現時,它就是函式表示式。

函式構造器

TypeScript 也支援使用名為 Function() 的內建 JavaScript 構造器來定義函式。

語法

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

示例

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

new Function() 是對構造器的呼叫,該構造器依次建立並返回函式引用。

編譯後,它將在 JavaScript 中生成相同的程式碼。

以上示例程式碼的輸出如下:

12 

遞迴和 TypeScript 函式

遞迴是一種透過讓函式重複呼叫自身直到得到結果來迭代操作的技術。當您需要在迴圈中重複呼叫同一個函式並使用不同的引數時,遞迴最適用。

示例 - 遞迴

function factorial(number) {
   if (number <= 0) {         // termination case
      return 1; 
   } else {     
      return (number * factorial(number - 1));     // function invokes itself
   } 
}; 
console.log(factorial(6));      // outputs 720 

編譯後,它將在 JavaScript 中生成相同的程式碼。

以下是它的輸出:

720

示例:匿名遞迴函式

(function () { 
   var x = "Hello!!";   
   console.log(x)     
})()      // the function invokes itself using a pair of parentheses ()

編譯後,它將在 JavaScript 中生成相同的程式碼。

其輸出如下:

Hello!!

Lambda 函式

Lambda 指的是程式設計中的匿名函式。Lambda 函式是表示匿名函式的簡潔機制。這些函式也稱為箭頭函式

Lambda 函式 - 解剖

Lambda 函式有 3 個部分:

  • 引數 - 函式可以可選地具有引數

  • 胖箭頭符號/lambda 符號 (=>) - 它也稱為轉到運算子

  • 語句 - 表示函式的指令集

提示 - 按照慣例,鼓勵使用單個字母引數來進行緊湊而精確的函式宣告。

Lambda 表示式

它是一個指向單行程式碼的匿名函式表示式。其語法如下所示:

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

示例:Lambda 表示式

var foo = (x:number)=>10 + x 
console.log(foo(100))      //outputs 110 

程式聲明瞭一個 lambda 表示式函式。該函式返回 10 與傳遞的引數的總和。

編譯後,它將生成以下 JavaScript 程式碼。

//Generated by typescript 1.8.10
var foo = function (x) { return 10 + x; };
console.log(foo(100));      //outputs 110

以下是以上程式碼的輸出:

110

Lambda 語句

Lambda 語句是一個指向程式碼塊的匿名函式宣告。當函式體跨越多行時,使用此語法。其語法如下所示:

( [param1, parma2,…param n] )=> {
 
   //code block
}

示例:Lambda 語句

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

函式的引用被返回並存儲在變數foo中。

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
var foo = function (x) {
   x = 10 + x;
   console.log(x);
};
foo(100);

以上程式的輸出如下:

110

語法變體

引數型別推斷

不必指定引數的資料型別。在這種情況下,引數的資料型別為 any。讓我們看看以下程式碼片段:

var func = (x)=> { 
   if(typeof x=="number") { 
      console.log(x+" is numeric") 
   } else if(typeof x=="string") { 
      console.log(x+" is a string") 
   }  
} 
func(12) 
func("Tom")

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
var func = function (x) {
   if (typeof x == "number") {
      console.log(x + " is numeric");
   } else if (typeof x == "string") {
      console.log(x + " is a string");
   }
};
func(12);
func("Tom");

其輸出如下:

12 is numeric 
Tom is a string

單個引數的可選括號

var display = x=> { 
   console.log("The function got "+x) 
} 
display(12)

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
var display = function (x) {
   console.log("The function got " + x);
};
display(12);

其輸出如下:

The function got 12

單個語句的可選大括號,無引數的空括號

以下示例顯示了這兩個語法變體。

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

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
var disp = function () {
   console.log("Function invoked");
};
disp();

其輸出如下:

Function invoked

函式過載

函式能夠根據提供的輸入以不同的方式執行。換句話說,程式可以有多個名稱相同但實現不同的方法。這種機制稱為函式過載。TypeScript 提供了對函式過載的支援。

要在 TypeScript 中過載函式,您需要按照以下步驟操作:

步驟 1 - 宣告多個名稱相同但函式簽名不同的函式。函式簽名包括以下內容。

  • 引數的資料型別

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;

注意 - 函式簽名不包括函式的返回型別。

步驟 2 - 宣告必須後跟函式定義。如果引數型別在過載期間不同,則應將引數型別設定為any。此外,對於上面解釋的情況 b,您可以在函式定義期間考慮將一個或多個引數標記為可選。

步驟 3 - 最後,您必須呼叫函式以使其發揮作用。

示例

現在讓我們看看以下示例程式碼:

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");
  • 前兩行描述了函式過載宣告。該函式有兩個過載:

    • 接受單個字串引數的函式。

    • 一個函式,分別接收兩個型別為數字和字串的值。

  • 第三行定義了函式。引數的資料型別設定為any。此外,第二個引數在此處是可選的。

  • 過載函式由最後兩條語句呼叫。

編譯後,它將生成以下 JavaScript 程式碼:

//Generated by typescript 1.8.10
function disp(x, y) {
   console.log(x);
   console.log(y);
}
disp("abc");
disp(1, "xyz");

以上程式碼將產生以下輸出:

abc 
1 
xyz 
廣告