TS为JS函数额外添加的一些功能

2,208 阅读4分钟

前言

函数是JS应用程序的基础之一,它也是定义行为的主要地方,它可以实现抽象层、模拟类、信息隐藏和模块等。今天我们就来讲讲TS中的函数,看看跟JS对比都添加了哪些功能

函数类型

为了让我们更容易使用,TS为函数添加了类型。

你可能会想怎么添加呢?

事实上,函数类型包含两部分:参数类型和返回值类型。

例如:

function add(x: number, y: number): number {
    return x + y;
}

如上例子,我们为参数xy都添加了类型,并且返回值也添加了类型,都为number

我们也可以写成表达式的方式

let add = function(x: number, y: number): number { return x + y; };

如上表达式,我们没有写返回值类型,原因是TS能够根据返回语句自动推断出返回值类型

当然,我们也可以书写完整函数类型,当写出完整函数类型的时候,这两部分都是需要的--参数类型和返回值类型。而且如果函数没有返回任何值,你也必须指定返回值类型为 void而不能留空

传参个数固定

TS中,传递给一个函数的参数个数必须与函数期望的参数个数一致,也就是说每个函数参数都是必须的。

但这不是指不能传递 nullundefined作为参数,而是说编译器检查用户是否为每个参数都传入了值。例如

function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}

上面这个函数,如果调用时,传递一个或者大于两个都是错误的。而这如果放在JS中是完全可以的,JS中我们可以选择传参的个数

你可能会想,有时候就是要根据不同情况,传递不同参数个数。

没错,TS中也有办法--可选参数

可选参数

TS里我们可以在参数名旁使用 ?实现可选参数的功能

比如,上例代码中,第二个参数设置成选传

function buildName(firstName: string, lastName?: string) {
    //...
}

需要特别注意的是:可选参数必须跟在必须参数后面。如果想让上例中的firstName作为可选参数,那么firstName必须放在后面,如下

function buildName(lastName: string, firstName?: string) {
    //...
}

默认参数

TS中也有默认参数,形式是参数后面跟=号,之后跟默认值,例如:

function buildName(lastName: string, firstName = "Alice") {
    //...
}

当用户没有传递这个参数或传递的值是undefined时,我们设置的默认值就会起作用

与普通可选参数不同,带默认值的参数不需要放在必须参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入 undefined值来获得默认值,如下:

function buildName(firstName = "Alice", lastName: string) {
    return firstName + " " + lastName;
}
buildName(undefined, "Mqid")

剩余参数

JS中,我们可以使用 arguments来访问所有传入的参数

而在TS中,可以把所有参数收集到一个变量里

例如:

function buildName(firstName: string, ...restOfName: string[]) {
  return firstName + " " + restOfName.join(" ");
}

函数重载

JS中,函数可以根据传入不同的参数而返回不同类型的数据,这再正常不过了

而在TS中要实现这样的场景,就得用到重载

不知道你是否听过重载?

简单来说,就是同一个函数提供多个函数类型定义来进行函数重载

比如官方给的这个例子:

let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
    // Check to see if we're working with an object/array
    // if so, they gave us the deck and we'll pick the card
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // Otherwise just let them pick the card
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);

let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

上述代码中,pickCard就为重载函数,并且重载的pickCard函数在调用的时候会进行正确的类型检查

注意,为了让编译器能够选择正确的检查类型,在定义重载的时候,一定要把最精确的定义放在最前面。原因是TS的处理流程会按特定的顺序查找重载列表

END

以上就是本文的所有内容,如有问题,欢迎指正~