前言
函数是JS
应用程序的基础之一,它也是定义行为的主要地方,它可以实现抽象层、模拟类、信息隐藏和模块等。今天我们就来讲讲TS
中的函数,看看跟JS对比都添加了哪些功能
函数类型
为了让我们更容易使用,TS为函数添加了类型。
你可能会想怎么添加呢?
事实上,函数类型包含两部分:参数类型和返回值类型。
例如:
function add(x: number, y: number): number {
return x + y;
}
如上例子,我们为参数x
和y
都添加了类型,并且返回值也添加了类型,都为number
我们也可以写成表达式的方式
let add = function(x: number, y: number): number { return x + y; };
如上表达式,我们没有写返回值类型,原因是TS能够根据返回语句自动推断出返回值类型
当然,我们也可以书写完整函数类型,当写出完整函数类型的时候,这两部分都是需要的--参数类型和返回值类型。而且如果函数没有返回任何值,你也必须指定返回值类型为 void
而不能留空
传参个数固定
在TS
中,传递给一个函数的参数个数必须与函数期望的参数个数一致,也就是说每个函数参数都是必须的。
但这不是指不能传递 null
或undefined
作为参数,而是说编译器检查用户是否为每个参数都传入了值。例如
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
以上就是本文的所有内容,如有问题,欢迎指正~