在微信中阅读,关注公众号:
CodeFit
。创作不易,如果你觉得这篇文章对你有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:
CodeFit
,为我的持续创作提供一些动力。
大纲
- 1. 上篇内容回顾:接口(Interface)
- 2. 一等公民:函数
- 3. 函数的输入和输出
- 4. 定义函数
- 5. 调用函数
- 6. 可选参数
- 7. 默认参数
- 8. 剩余参数
- 9. 函数表达式
- 10. 函数作为类型
- 11. 使用接口描述函数类型
- 12. 高阶函数
- 13. 总结
上篇内容回顾:接口(Interface)
接口是一种规范和契约,用于定义对象的结构,描述了对象应该包含哪些属性及其可执行的操作(方法)。另外,通过接口定义对象时,如果对象不符合接口定义,TypeScript 编译器会发出警告。
一等公民:函数
本次内容,我们将开始回顾 函数 的知识点。
不管是在 JavaScript,还是 TypeScript 中,函数都被视为一等公民,这意味着函数可以作为参数传递、作为返回值、赋值给变量、存储在数据结构中(如数组)。
一等公民 的特性使得在 TypeScript 中,函数具有很大的灵活性和强大的表达能力。
函数的输入和输出
函数可以在程序中 执行特定的任务,并且在需要时可以 多次调用。
我们可以将函数看作是一个微型的程序,这个程序的运行方式通常是,你给它一些 “输入”(参数),它会给你一些 “输出”(返回值)。
所以,一个函数的构成,我们主要关注两个部分:输入(参数) 和 输出(返回值)。
这些概念和 JavaScript 并没有什么不同,重点是,在定义函数时,TypeScript 可以对这两部分进行 类型约定。
定义函数
定义一个函数,首先要使用 function 进行声明,然后要给它起一个 名字,比如 add
,接着在 圆括号 () 里面指定它需要的 参数,比如 x
和 y
。最后在 花括号 {} 里面写上这个函数要做的事情,并且可以使用 return 关键字把 结果
进行返回。
function add(x: number, y: number): number {
return x + y;
}
x: number
和y: number
定义了函数的 参数类型。: number
在函数签名后定义了函数的 返回值类型。
在 TypeScript 中定义函数的方式其实与 JavaScript 相同,但可以添加 类型注解 来规定参数和返回值的 数据类型。
函数定义好后,需要 调用 才会执行,否则它什么也不会做。
调用函数
调用一个函数就像启动一个程序,并且提供 正确的输入(参数)。
如果函数定义了返回值,那么函数执行结束时,我们可以得到 返回值,这是函数执行完毕后返回的结果。
参考上面函数定义的例子,我们通过 return 关键字设置了返回值。
let result = add(1, 2); // 正确
console.log(result); // 输出: 3
let result = add(1, '2'); // 错误:参数 '2' 不是 number 类型
let result = add(1, 2, 3); // 错误:参数数量不匹配
可选参数
在 JavaScript 中,所有的参数都是 可选 的,这代表我们即使定义函数时有参数,但是在调用函数时,可以不传递它们。
如果没有传递,调用函数时得到的参数值就是
undefined
。
而在 TypeScript 中,默认情况下,参数如果有的话必须传递,而 不是可选项。
但是我们可以使用 ?
语法来显式标记参数为 可选。
也就是,当我们使用 ?
标记参数为可选参数后,才可以像 JavaScript 一样,函数调用时,可以选择是否传递这个参数。
TypeScript 引入 可选参数 的好处是代码的意图更明确。
另外一个好处是,可以让我们实现更严格的类型检查,下面是一个示例。
function add(x: number, y: number, z?: number): number {
if (typeof z === 'number') {
return x + y + z;
} else {
return x + y;
}
}
let result1 = add(1, 2); // 正确
let result2 = add(1, 2, 3); // 正确
注意:可选参数必须放在最后。
下面是一个编写可选函数时的 错误示例。
function add(x: number, y?: number, z: number): number {
// 错误:可选参数必须放在最后
}
默认参数
除了 可选参数,TypeScript 还提供了 默认参数。
使用 默认参数 后,如果没有传递参数,就会使用默认值,而不是 undefined
。
function greet(name: string = 'Guest') {
console.log(`Hello, ${name}`);
}
greet(); // 输出: Hello, Guest
greet('CodeFit 公众号'); // 输出: Hello, 公众号:CodeFit
在这个例子中,如果没有传递 name
参数,默认值 'Guest'
会被使用。
剩余参数
TypeScript 还提供了 剩余参数(Rest Parameters),通过使用 ...
语法来获取 多个参数。
...
语法允许函数接受不确定数量的参数作为 数组,从而提供了一种在 TypeScript 中表示 可变函数 的方法。
function sum(...theArgs) {
let total = 0;
for (const arg of theArgs) {
total += arg;
}
return total;
}
console.log(sum(1, 2, 3)); // 相加后,输出: 6
console.log(sum(1, 2, 3, 4)); // 相加后,输出:10
在这个例子中,如果没有传递 name
参数,默认值 'Guest'
会被使用。
函数表达式
前面我们通过 function 关键字 的方式定义函数。
但其实还可以通过 函数表达式 的方式进行定义。
const add = (x: number, y: number, z?: number): number => {
if (typeof z === 'number') {
return x + y + z;
} else {
return x + y;
}
};
let result = add(1, 2); // 正确
函数作为类型
函数不是只有输入和输出才有类型,函数本身也可以看做类型。
这代表我们可以声明一个 函数类型 的变量,也就是使用函数类型来定义一个变量的类型。
函数类型变量目的是让这个变量只能存储符合特定签名的函数。还记得上一篇内容中讲的方法签名吗?和这里的函数签名的概念是一样的,
如果我们的目的就是创建一个 函数类型,那么,我们可以使用 类型别名(type
) 来进行 函数类型 的定义,下面是一个例子。
// 定义一个函数类型,接受两个 number 类型的参数,返回一个 number 类型的值
type Add = (x: number, y: number) => number;
// 使用函数类型注解来定义一个变量
const add: Add = (x, y) => {
return x + y;
};
console.log(add(2, 3)); // 输出: 5
使用接口描述函数类型
除了使用 类型别名(type),我们还可以使用 接口(interface) 来定义函数类型。
也就是说接口不仅可以描述 对象类型,还可以描述 函数类型。
// 定义接口
interface Add {
(x: number, y: number): number
}
// 实现接口
const add: Add = (x, y) => {
return x + y
}
console.log(add(2, 3)) // 输出: 5
在这个例子中:
interface Add { (x: number, y: number): number }
定义了一个 函数类型接口Add
,它接受两个number
类型的参数,并返回一个number
类型的值。const add: Add = (x, y) => { return x + y; }
定义了一个变量add
,并赋值为一个符合Add
接口的函数。
高阶函数
高阶函数 通常是指接收一个或多个函数作为参数,或返回一个函数的函数。
接收函数作为参数,如下示例。
function repeat(action: () => void, times: number) {
for (let i = 0; i < times; i++) {
action();
}
}
repeat(() => console.log('Hello!'), 3);
// 输出:
// Hello!
// Hello!
// Hello!
也可以是返回函数,如下示例。
function createMultiplier(factor: number): (number: number) => number {
return (number: number) => number * factor;
}
const double = createMultiplier(2);
console.log(double(5)); // 输出: 10
const triple = createMultiplier(3);
console.log(triple(5)); // 输出: 15
总结
在本篇文章中,我们回顾了 TypeScript 中的 函数 概念。
函数在 TypeScript 中被视为 一等公民。
通过为函数的 参数 和 返回值 添加类型注解,可以确保代码的类型安全性和可读性。
还回顾了如何定义和调用函数,包括 可选参数、默认参数 和 剩余参数。
特别的,我们探讨了函数本身作为类型,,这让我们能够让定义的变量存储符合特定签名的函数,这样的变量类型也称作 函数类型。
我们可以通过 类型别名(type) 和 接口 定义函数类型,从而提高了代码的灵活性和表达能力。
最后,我们介绍了 高阶函数 的概念,展示了如何将函数作为参数传递或返回,从而实现更高层次的抽象和代码复用。
通过这些内容,希望你能对 TypeScript 中的函数有一个很好的回顾,为之后的项目内容打下坚实的基础。
感谢你的阅读!
如果你觉得这篇文章对你有帮助,请点赞、分享,并关注 CodeFit,这样你就不会错过更多的精彩内容。
同时,你的 支持 和 反馈 对我非常重要,欢迎在评论区留言,与我互动。
谢谢大家,下次见!