Function(函式分享)第二節

yxl87發表於2020-11-20

一、型別註解

1.1 型別註解

函式的型別註解分為兩個部分:引數型別註解和返回值型別註解。其中返回值型別註解有時候我們可以直接省略,因為Typescript可以根據返回的語句來自動判斷出返回值的型別。

function add (x: number, y: number): number { 
    return x + y;
} // 匿名函式完整的引數註解;
let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; }; // 匿名函式表示式完整的引數註解;
/*這其中,表示式左右的型別註解中,引數名稱可以不一致,我們需要把順序對應上即可。當函式沒有返回值的時候,我們用void型別進行註解。*/

當我們指定了賦值語句一側的型別之後,我們是可以忽略另一側的型別註解,在Typescript的型別推論中,被稱作“按上下文歸類”。

let myAdd = function(x: number, y: number): number {
  return x + y; 
}; //省略左側的型別註解
let myAdd: (baseValue: number, increment: number) => number = function(x, y) { return x + y; }; 
// 省略右側的型別註解,並且左右側的引數名稱並不相同。

除了基本的型別註解之外,我們還有其他的方式來描述這兩部分型別。
例如使用變數來單獨定義引數:

let param: { a: number };
function foo(param) {}

還可以利用介面的形式定義引數:

interface Param {
    a: number;
}
function foo (param: Param): number {
    return 1;
}

同時我們也可用這些方法去定義返回值的型別。
除此之外,我們還可以利用介面直接定義函式:

interface SearchFunc {
    (a: number, b: number): number;
}
let search : SearchFunc;
search = function(a: number, b: number) {
    return a+b;
}

1.2 可選引數和預設引數

在Typescript中定義函式是,定義了引數的個數及型別。當呼叫該函式時,必須嚴格遵守其個數和引數型別。但是在Javascript中,我們可以選擇性傳遞引數,當某個引數不傳值的時候,該引數的值為undefined。在TS中,我們可以使用?來表示該引數為可選引數。

let myAdd = function (a: number, b?: number) { //b為可選引數 
    if (b === undefined) { 
        return a;
    }
    return a + b;
}

除了使用可選引數之外,我們還可以給引數設定預設值:

let myAdd = function (a: number, b = 0) { //b不傳值時,該值為0
    return a + b
}

1.3 剩餘引數

當傳入的引數不確定數量時,可以使用…來表示剩餘引數,進行傳值。這與ES6中的用法是一致的。

function plus(firstNum: number, ...restofNum: number[]) {
    return firstNum + restofNum.reduce((a, b) => a + b);
} // 我們用一個數字型別的陣列來規定剩餘引數的型別。
let a = plus(1, 2, 3, 4);
console.log(a); //10

二、函式過載

我們在JS中定義的函式,可以接受任意的引數,這裡的任意有兩層意義:一個是任意個數,一個是任意型別(JS中沒有型別檢查機制)。因此我們在構建一個健壯性足夠強的函式時,通常會用if語句或switch語句在其中進行型別或個數的判斷,來執行不同的邏輯。這在程式碼的意義上,也算是一種過載。但是其最大的問題在於,過載的邏輯是耦合在一起的,沒有做到邏輯分離。然而TS的過載,實際上也沒有很好的解決這個問題。

我們在宣告過載的時候需要注意以下幾點:

  • 過載函式只有函式宣告,沒有函式體。其本質是記錄你呼叫函式的方式。
  • 函式實現必須緊跟函式過載宣告。
  • 過載函式必須和其實現的引數個數保持一致,不能出現函式實現中不能滿足的過載宣告。
function padding(all: number); // 當傳入一個值的情況;
function padding(topAndBottom: number, leftAndRight: number) : {
    top: string;
    right: string;
    bottom: string;
    left: string;
}; //傳入兩個值的情況
function padding(top: number, right: number, bottom: number, left: number) : {
    top: number;
    right: number;
    bottom: number;
    left: number;
}; //傳入四個值的情況
function padding(a: number, b?: number, c?:number, d?:number) {
    if (b === undefined && c === undefined && d === undefined) { 
        b = c = d = a; 
    } else if (c === undefined && d === undefined) {
        c = a;
        d = b;
    }
    return {
        top: a,
        right: b,
        bottom: c,
        left: d,
    };
}
/*函式實現體內,通過if來處理不同引數情況的邏輯*/

相關文章