今天学习 TypeScript 的函数,包括函数类型、可选参数、默认参数、剩余参数。
- 函数声明和表达式
- 函数类型
- 可选参数和默认参数
- 剩余参数
在 TypeScript 中,函数是编程的核心概念之一。它们允许我们将代码组织成可重用的块,并提供了强大的抽象能力。在本文中,我们将深入探讨 TypeScript 函数的各种特性,包括函数类型、可选参数、默认参数和剩余参数。
一.函数声明和表达式
在 TypeScript 中,我们可以通过函数声明或函数表达式来定义函数。函数声明具有函数名,而函数表达式则没有。
// 函数声明
// 定义了一个名为 add 的函数,它接受两个数字类型的参数 a 和 b
// 并返回它们的和,返回值类型也是数字
function add(a: number, b: number): number {
return a + b; // 返回参数 a 和 b 的和
}
// 函数表达式
// 定义了一个匿名函数并将其赋值给变量 subtract
// 这个函数接受两个数字类型的参数 a 和 b,并返回它们的差,返回值类型也是数字
const subtract = (a: number, b: number): number => {
return a - b; // 返回参数 a 减去 b 的结果
};
(1)函数声明
- 使用
function
关键字来声明。 - 函数声明会被提升,可以在声明之前调用它。
- 通常用于顶层作用域或模块中。
greet('清清ww'); // 输出: Hello, 清清ww!
function greet(name) {
console.log('Hello, ' + name + '!');
}
greet('清清ww'); // 输出: Hello, 清清ww!
在这个例子中,我们定义了一个名为 greet
的函数,它接受一个参数 name
并打印一条问候语。由于函数声明会被提升,我们可以在声明之前调用 greet
函数。
(2)函数表达式
- 使用变量赋值的方式来定义函数。
- 函数表达式不会提升,必须在定义之后才能调用。
- 可以立即调用或作为匿名函数传递给其他函数。
const greet = function(name) {
console.log('Hello, ' + name + '!');
};
greet('清清ww'); // 输出: Hello, 清清ww!
在这个例子中,我们使用了一个函数表达式来定义一个匿名函数,并将其赋值给变量 greet
。然后通过变量名 greet
来调用这个函数。由于函数表达式不会被提升,我们不能在声明之前调用它。
二.函数类型
TS 允许我们为函数定义类型。函数类型包括参数类型和返回类型。
在 TypeScript 中,函数类型是指函数的参数类型和返回类型的组合。TypeScript 允许我们为函数定义类型,以确保函数的参数和返回值符合预期的类型。函数类型通常用于函数声明、函数表达式和箭头函数。
1.函数类型声明
函数类型声明是一种显式指定函数参数类型和返回类型的方式。它使用 function
关键字,后跟参数列表和返回类型。
// 函数类型声明
let greet: (name: string) => string;
// 函数实现
greet = function(name: string): string {
return 'Hello, ' + name + '!';
};
const message = greet('清清ww');
console.log(message); // 输出: Hello, 清清ww!
在上面的例子中,我们首先声明了一个函数类型 greet
,它接受一个 string
类型的参数 name
,并返回一个 string
类型的值。然后,我们为 greet
赋予了一个具体的函数实现。
2.函数类型表达式
函数类型表达式是一种更简洁的函数类型声明方式。它使用箭头函数语法 =>
来定义函数类型。
// 函数类型表达式
let greet: (name: string) => string;
// 函数实现
greet = (name: string): string => {
return 'Hello, ' + name + '!';
};
const message = greet('清清ww');
console.log(message); // 输出: Hello, 清清ww!
在上面的例子中,我们使用箭头函数语法来定义函数类型 greet
。这种方式更加简洁,但功能与函数类型声明相同。
3.函数类型推断
TypeScript 具有类型推断功能,它可以根据函数的实现自动推断函数的类型。如果没有显式指定函数类型,TypeScript 会尝试推断函数的类型。
// 函数类型推断
let greet = function(name: string): string {
return 'Hello, ' + name + '!';
};
const message = greet('清清ww');
console.log(message); // 输出: Hello, 清清ww!
在上面的例子中,我们没有显式指定函数类型,但 TypeScript 会根据函数的实现自动推断函数的类型。
三.可选参数和默认参数
TypeScript 允许我们定义可选参数和默认参数。可选参数在函数调用时可以省略,而默认参数在未提供值时使用默认值。
1.可选参数
可选参数是指在调用函数时可以省略的参数,通过在参数后面添加一个问号 ?
来表示该参数是可选的。可选参数通常位于参数列表的末尾。
// 可选参数
function greet(name: string, age?: number): string {
if (age) {
return `你好${name},你${age} 岁了!`;
} else {
return `你好, ${name}!`;
}
}
console.log(greet('清清ww')); // 输出: 你好, 清清ww!
console.log(greet('清清ww', 3)); // 输出: 你好, 清清ww, 你3岁了!
在上面的例子中,greet
函数的 age
参数是可选的。当调用 greet
函数时,如果没有提供 age
参数,函数会返回一个没有年龄信息的问候。
2.默认参数
默认参数是指在调用函数时如果没有提供该参数,则使用默认值的参数。在 TypeScript 中,通过在参数后面赋值来设置默认值。
// 默认参数
function greet(name: string, age: number = 3): string {
return `你好, ${name}, 你${age}岁了!`;
}
console.log(greet('清清ww')); // 输出: 你好, 清清ww, 你3岁了!
console.log(greet('清清ww', 3)); // 输出: 你好, 清清ww, 你3岁了!
在上面的例子中,greet
函数的 age
参数有一个默认值 3。当调用 greet
函数时,如果没有提供 age
参数,函数会使用默认值 3
。
3. 可选参数和默认值的优先级
当同时使用可选参数和默认值时,它们的优先级是按照参数的顺序来确定的。
- 如果一个参数既有默认值又是可选的,那么在调用函数时,如果省略了这个参数,就会使用默认值。
- 如果一个参数是可选的但没有默认值,那么在调用函数时,可以省略这个参数,函数会将其视为
undefined
。 - 如果一个参数有默认值但不是可选的,那么在调用函数时,必须提供这个参数的值,否则会使用默认值。
// 可选参数和默认参数的优先级
function greet(name: string, age?: number = 3): string {
return `你好, ${name}, 你${age} 岁了!`;
}
console.log(greet('清清ww')); // 输出: 你好, 清清ww, 你3岁了!
console.log(greet('清清ww', undefined)); // 输出: 你好, 清清ww, 你3岁了!
console.log(greet('清清ww', 4)); // 输出: 你好, 清清ww, 你4岁了!
在上面的例子中,age
参数既被标记为可选,又被赋予了默认值3。当调用 greet
函数时,如果没有提供 age
参数,函数会使用默认值3。如果提供了 age
参数,即使值为 undefined
,函数也会使用默认值 3
。
四.剩余参数
剩余参数是通过在参数名前加上三个点(…)来定义的,并且它必须是函数的最后一个参数。它允许我们将多个参数收集到一个数组中(在处理不确定数量的参数时非常有用)。这样就可以在函数内部使用这个参数作为数组来访问所有的剩余参数。
举个例子:一个名为 createPerson
的函数,它接受一个对象和一个剩余参数:
// 定义一个 Person 类型,包含 name, age 和可选的 hobbies 数组
type Person = {
name: string;
age: number;
hobbies?: string[];
};
// 定义一个函数 createPerson,接受一个 Person 类型的对象和剩余的字符串参数作为爱好
function createPerson(person: Person, ...hobbies: string[]): Person {
// 检查是否有提供爱好
if (hobbies.length > 0) {
// 如果有爱好,将它们赋值给 person 对象的 hobbies 属性
person.hobbies = hobbies;
}
// 返回修改后的 person 对象
return person;
}
// 创建一个基础的人物对象,包含 name 和 age 属性
let basePerson: Person = {
name: '清清ww',
age: 3,
};
// 使用 createPerson 函数添加额外的爱好,剩余参数 'eat', 'play', 'sleep' 被视为一个数组
let personWithHobbies = createPerson(basePerson, 'eat', 'play', 'sleep');
// 打印包含爱好的 person 对象
console.log(personWithHobbies);
在这个例子中,createPerson
函数接受一个 Person
类型的对象和一个剩余参数 。剩余参数是一个二维数组,其中每个元素是一个 [key, value]
对,用于添加或更新 Person
对象的属性。
调用 createPerson
函数时,我们首先创建了一个基础的人物对象 basePerson
,然后使用剩余参数添加了爱好 hobbies
。打印出的personWithHobby
对象包含了所有的基础属性和额外的爱好属性。
注意:剩余参数必须是函数的最后一个参数。如果在剩余参数之后定义了其他参数,TypeScript 编译器会报错。
本文完~