5.函数 副本.md 来源:https://my.feishu.cn/file/GvcKblz0FoHD7ZxFOhRcQTWpnrd 采集状态:已完成正文采集;已从查看代码模式逐行提取,行号 1 至 92 连续,并核对滚动到底。 在任何编程语言中,函数都是构建逻辑的基本单元。它们帮助我们封装代码、实现复用并构建复杂的应用。当我们进入 TypeScript 的世界,函数的能力得到了进一步的增强——这主要归功于其强大的类型系统。 在日常开发中,为函数精确定义输入和输出是保障代码健壮性的关键。接下来,我们将一起探讨 TypeScript 是如何通过类型注解、可选参数和默认参数,来优化函数定义的。 ### 为函数添加类型注解 在 TypeScript 中,最直接的增强是为函数的参数和返回值添加明确的类型注解。这不仅是 TypeScript 的核心特性,也是编写高质量、可维护代码的基石。 它的语法非常直观: * 在参数名后使用冒号 `(:)` 来指定该参数的类型。 * 在函数参数列表的括号后使用冒号 `(:)` 来指定函数的返回值类型。 让我们来看一个简单的例子。假设我们需要一个函数,它接收两个数字作为参数,并返回它们的和。 ```typescript function add(a: number, b: number): number { return a + b; } ``` 通过这种方式,我们向 TypeScript 编译器以及其他开发者清晰地传达了此函数的“契约”: 1. 参数 `a` 必须是 `number` 类型。 2. 参数 `b` 必须是 `number` 类型。 3. 该函数必须返回一个 `number` 类型的值。 如果我们在调用 `add` 函数时传入了非数字类型的参数,TypeScript 编译器会在编译阶段就立刻抛出错误,从而避免了在运行时可能出现的意外行为。这种“前置”的错误捕获机制,是 TypeScript 相比于原生 JavaScript 的一大优势。 ### 赋予函数更多灵活性:可选参数与默认参数 虽然严格的类型定义是好事,但在某些场景下,我们也需要函数具备一定的灵活性。例如,一个函数的某些参数并非每次调用都需要传递。针对这种情况,TypeScript 提供了可选参数和默认参数两种实用的机制。 #### 1. 可选参数 当我们希望函数的某个参数可以被“省略”时,可以使用可选参数。语法是在参数名后、冒号前添加一个问号 `(?)`。 我们来设想一个向用户打招呼的函数。这个函数必须知道用户的名字,但问候语可以是可选的。 ```typescript function greet(name: string, salutation?: string): string { if (salutation) { return `${salutation}, ${name}!`; } else { return `Hello, ${name}!`; } } // 两种有效的调用方式 console.log(greet("Alice")); // 输出: Hello, Alice! console.log(greet("Bob", "Good morning")); // 输出: Good morning, Bob! ``` 需要注意的是,当一个可选参数未被传递时,它在函数内部的值是 `undefined`。因此,我们需要在函数体内进行相应的逻辑判断。 此外,一个重要的规则是:**可选参数必须位于必选参数之后**。这是为了让 TypeScript 能够正确地将传入的参数与函数定义中的参数对应起来。 #### 2. 默认参数 默认参数与可选参数解决的是类似的问题,但实现方式略有不同。它允许我们为参数提供一个默认值,当调用者没有传递该参数时,函数将自动使用这个预设的值。 语法非常简洁,直接在参数声明后使用等号 `(=)` 即可。 我们来重构一下上面的 `greet` 函数,这次使用默认参数: ```typescript function greetWithDefault(name: string, salutation: string = "Hello"): string { return `${salutation}, ${name}!`; } // 两种调用方式及其结果 console.log(greetWithDefault("Alice")); // 输出: Hello, Alice! console.log(greetWithDefault("Bob", "Good morning")); // 输出: Good morning, Bob! ``` 使用默认参数的好处是代码更显简洁。我们不再需要在函数体内检查参数是否为 `undefined`,因为 TypeScript 已经保证了 `salutation` 参数总会有一个 `string` 类型的值。 当一个参数被赋予了默认值,它实际上也变成了“可选”的。与可选参数不同的是,带有默认值的参数不强制要求必须放在参数列表的末尾。然而,为了保持代码的可读性和一致性,通常我们还是建议将它们放在必选参数之后。 ### 总结 通过本次梳理,我们可以看到 TypeScript 为函数带来了显著的改进: * **类型注解**:通过为参数和返回值添加类型,我们极大地提升了代码的明确性和可靠性,能在开发早期就发现潜在的类型错误。 * **可选参数 `(?)`**:提供了定义非必需参数的灵活性,调用时可以省略这些参数。 * **默认参数 `(=)`**:在参数未传递时为其提供预设值,简化了函数内部的逻辑处理,并使代码更加清晰。 掌握这些特性,是编写现代化、高健壮性 TypeScript 代码的基础。在日常开发中,结合运用这些工具,我们可以构建出既灵活又安全的函数,从而为整个应用的质量提供坚实的保障。