差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
| typescript:第三章下_二元运算符与三元运算符 [2026/04/27 20:25] – 移除 - 外部编辑 (未知日期) 127.0.0.1 | typescript:第三章下_二元运算符与三元运算符 [2026/04/27 20:31] (当前版本) – 张叶安 | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| + | ====== 第三章:TypeScript 中的二元运算符与三元运算符 ====== | ||
| + | |||
| + | |||
| + | ===== 3.1 运算符的基本概念 ===== | ||
| + | |||
| + | 在 TypeScript 中,运算符是用于对一个或多个值进行操作的符号。例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = 1 + 2; | ||
| + | </ | ||
| + | |||
| + | 在这段代码中: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * 表达式最终会产生一个值,即 '' | ||
| + | |||
| + | 根据操作数数量的不同,运算符可以分为: | ||
| + | |||
| + | * 一元运算符:只需要一个操作数,例如 '' | ||
| + | * 二元运算符:需要两个操作数,例如 '' | ||
| + | * 三元运算符:需要三个操作数,例如 '' | ||
| + | |||
| + | 本章重点讲解二元运算符和三元运算符。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.2 什么是二元运算符 ===== | ||
| + | |||
| + | 二元运算符,英文通常称为 Binary Operator,是指需要两个操作数才能完成运算的运算符。 | ||
| + | |||
| + | 基本格式如下: | ||
| + | |||
| + | <code typescript> | ||
| + | 左操作数 运算符 右操作数 | ||
| + | </ | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const sum = 10 + 20; | ||
| + | </ | ||
| + | |||
| + | 其中: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | 再比如: | ||
| + | |||
| + | <code typescript> | ||
| + | const isAdult = age >= 18; | ||
| + | </ | ||
| + | |||
| + | 其中: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * ''> | ||
| + | * 整个表达式的结果是一个布尔值 | ||
| + | |||
| + | TypeScript 中的大多数常用运算符都是二元运算符。例如: | ||
| + | |||
| + | <code typescript> | ||
| + | a + b | ||
| + | a - b | ||
| + | a * b | ||
| + | a / b | ||
| + | a % b | ||
| + | a ** b | ||
| + | a === b | ||
| + | a !== b | ||
| + | a > b | ||
| + | a < b | ||
| + | a >= b | ||
| + | a <= b | ||
| + | a && b | ||
| + | a || b | ||
| + | a ?? b | ||
| + | a = b | ||
| + | a += b | ||
| + | </ | ||
| + | |||
| + | 这些写法都有一个共同点:运算符左右两边各有一个表达式。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.3 二元运算符的基本特点 ===== | ||
| + | |||
| + | 二元运算符有以下几个重要特点。 | ||
| + | |||
| + | 第一,二元运算符必须有两个操作数。 | ||
| + | |||
| + | 例如下面的代码是正确的: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = a + b; | ||
| + | </ | ||
| + | |||
| + | 但是下面的代码是不完整的: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = a +; | ||
| + | </ | ||
| + | |||
| + | 因为 '' | ||
| + | |||
| + | 第二,二元运算符通常会产生一个新值。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = 3 * 4; | ||
| + | </ | ||
| + | |||
| + | 表达式 '' | ||
| + | |||
| + | 第三,不同的二元运算符有不同的返回类型。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = 1 + 2; // number | ||
| + | const b = " | ||
| + | const c = 10 > 5; // boolean | ||
| + | const d = true && false; // boolean | ||
| + | </ | ||
| + | |||
| + | 在 TypeScript 中,编译器会根据运算符和操作数类型推断表达式的结果类型。 | ||
| + | |||
| + | 第四,二元运算符可能涉及类型转换。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = " | ||
| + | </ | ||
| + | |||
| + | 这里的结果不是数字 '' | ||
| + | |||
| + | TypeScript 虽然增加了静态类型检查,但运行时行为仍然遵循 JavaScript。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.4 算术二元运算符 ===== | ||
| + | |||
| + | 算术运算符用于进行数学计算。常见的算术二元运算符包括: | ||
| + | |||
| + | ^ 运算符 ^ 名称 ^ 示例 ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | ''/'' | ||
| + | | '' | ||
| + | | $**$ | 幂运算 | $a ** b$ | | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = 10; | ||
| + | const b = 3; | ||
| + | |||
| + | const sum = a + b; // 13 | ||
| + | const diff = a - b; // 7 | ||
| + | const product = a * b; // 30 | ||
| + | const quotient = a / b; // 3.3333333333333335 | ||
| + | const remainder = a % b; // 1 | ||
| + | const power = a ** b; // 1000 | ||
| + | </ | ||
| + | |||
| + | 在 TypeScript 中,这些算术运算符通常要求操作数是数字类型,或者是可以参与数值运算的类型。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const x: number = 10; | ||
| + | const y: number = 5; | ||
| + | |||
| + | const result = x - y; | ||
| + | </ | ||
| + | |||
| + | 这是合理的。 | ||
| + | |||
| + | 但是下面的代码通常不推荐: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = " | ||
| + | </ | ||
| + | |||
| + | 虽然 JavaScript 运行时可能会把字符串 ''" | ||
| + | |||
| + | 更推荐的写法是: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = Number(" | ||
| + | const result = value - 5; | ||
| + | </ | ||
| + | |||
| + | 这样代码意图更加清晰。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.5 加号运算符的特殊性 ===== | ||
| + | |||
| + | 在 TypeScript 和 JavaScript 中,'' | ||
| + | |||
| + | 数字加法: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = 1 + 2; // 3 | ||
| + | </ | ||
| + | |||
| + | 字符串拼接: | ||
| + | |||
| + | <code typescript> | ||
| + | const message = " | ||
| + | </ | ||
| + | |||
| + | 数字与字符串相加: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = "Age: " + 18; // "Age: 18" | ||
| + | </ | ||
| + | |||
| + | 在这种情况下,数字会被转换为字符串,然后进行拼接。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = 1 + 2 + " | ||
| + | console.log(a); | ||
| + | </ | ||
| + | |||
| + | 分析过程如下: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * 最终结果是字符串 ''" | ||
| + | |||
| + | 再看另一个例子: | ||
| + | |||
| + | <code typescript> | ||
| + | const b = " | ||
| + | console.log(b); | ||
| + | </ | ||
| + | |||
| + | 分析过程如下: | ||
| + | |||
| + | * ''" | ||
| + | * ''" | ||
| + | |||
| + | 因此,在实际开发中,如果希望明确进行数字计算,应先把数据转换为数字: | ||
| + | |||
| + | <code typescript> | ||
| + | const input = " | ||
| + | const result = Number(input) + 20; | ||
| + | </ | ||
| + | |||
| + | 如果希望明确进行字符串拼接,可以使用模板字符串: | ||
| + | |||
| + | <code typescript> | ||
| + | const name = " | ||
| + | const age = 18; | ||
| + | |||
| + | const message = `${name} is ${age} years old.`; | ||
| + | </ | ||
| + | |||
| + | 模板字符串通常比多个 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.6 赋值二元运算符 ===== | ||
| + | |||
| + | 赋值运算符用于把右侧的值赋给左侧变量或属性。 | ||
| + | |||
| + | 最基本的赋值运算符是: | ||
| + | |||
| + | <code typescript> | ||
| + | = | ||
| + | </ | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | let count = 0; | ||
| + | count = 10; | ||
| + | </ | ||
| + | |||
| + | 这里的 '' | ||
| + | |||
| + | * 左操作数是 '' | ||
| + | * 右操作数是 '' | ||
| + | * 运算符是 '' | ||
| + | |||
| + | 常见的复合赋值运算符包括: | ||
| + | |||
| + | ^ 运算符 ^ 含义 ^ 等价写法 ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | ''/ | ||
| + | | '' | ||
| + | | $**=$ | 幂运算后赋值 | $a = a ** b$ | | ||
| + | | ''&& | ||
| + | | '' | ||
| + | | ''?? | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | let count = 10; | ||
| + | |||
| + | count += 5; // 15 | ||
| + | count -= 3; // 12 | ||
| + | count *= 2; // 24 | ||
| + | count /= 4; // 6 | ||
| + | count %= 4; // 2 | ||
| + | </ | ||
| + | |||
| + | 需要注意的是,复合赋值并不总是简单的文本替换。例如: | ||
| + | |||
| + | <code typescript> | ||
| + | obj.value += 1; | ||
| + | </ | ||
| + | |||
| + | 大致可以理解为: | ||
| + | |||
| + | <code typescript> | ||
| + | obj.value = obj.value + 1; | ||
| + | </ | ||
| + | |||
| + | 但在涉及 getter、setter 或复杂属性访问时,实际求值过程可能有更细致的规则。因此,在学习阶段可以先按等价写法理解,在深入阶段再研究求值顺序。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.7 比较二元运算符 ===== | ||
| + | |||
| + | 比较运算符用于比较两个值,并返回布尔值。 | ||
| + | |||
| + | 常见比较运算符如下: | ||
| + | |||
| + | ^ 运算符 ^ 名称 ^ 示例 ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | ''>'' | ||
| + | | ''<'' | ||
| + | | ''> | ||
| + | | ''< | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const age = 20; | ||
| + | |||
| + | const a = age > 18; // true | ||
| + | const b = age < 18; // false | ||
| + | const c = age >= 20; // true | ||
| + | const d = age <= 20; // true | ||
| + | </ | ||
| + | |||
| + | 在 TypeScript 中,推荐优先使用严格相等 '' | ||
| + | |||
| + | 原因是 '' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | console.log(1 == " | ||
| + | console.log(1 === " | ||
| + | </ | ||
| + | |||
| + | 第一行中,'' | ||
| + | |||
| + | 第二行中,'' | ||
| + | |||
| + | 在 TypeScript 项目中,使用 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.8 逻辑二元运算符 ===== | ||
| + | |||
| + | 逻辑二元运算符主要包括: | ||
| + | |||
| + | ^ 运算符 ^ 名称 ^ 示例 ^ | ||
| + | | ''&&'' | ||
| + | | '' | ||
| + | |||
| + | 虽然逻辑非 '' | ||
| + | |||
| + | 逻辑与 ''&&'' | ||
| + | |||
| + | * 如果左侧是假值,则返回左侧 | ||
| + | * 如果左侧是真值,则返回右侧 | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const result1 = true && " | ||
| + | const result2 = false && " | ||
| + | </ | ||
| + | |||
| + | 逻辑或 '' | ||
| + | |||
| + | * 如果左侧是真值,则返回左侧 | ||
| + | * 如果左侧是假值,则返回右侧 | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const result1 = " | ||
| + | const result2 = "" | ||
| + | </ | ||
| + | |||
| + | 需要注意的是,''&&'' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const name = ""; | ||
| + | const displayName = name || " | ||
| + | |||
| + | console.log(displayName); | ||
| + | </ | ||
| + | |||
| + | 这里 '' | ||
| + | |||
| + | JavaScript 中常见的假值包括: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * $'' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | 除了这些值之外,大多数值都是真值。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.9 逻辑短路特性 ===== | ||
| + | |||
| + | 逻辑运算符具有短路特性。 | ||
| + | |||
| + | 所谓短路,是指如果通过左操作数已经能够确定整个表达式的结果,那么右操作数就不会再被执行。 | ||
| + | |||
| + | 逻辑与 ''&&'' | ||
| + | |||
| + | <code typescript> | ||
| + | function sayHello() { | ||
| + | console.log(" | ||
| + | return true; | ||
| + | } | ||
| + | |||
| + | const result = false && sayHello(); | ||
| + | </ | ||
| + | |||
| + | 在这段代码中,'' | ||
| + | |||
| + | 逻辑或 '' | ||
| + | |||
| + | <code typescript> | ||
| + | function getDefaultName() { | ||
| + | console.log(" | ||
| + | return " | ||
| + | } | ||
| + | |||
| + | const name = " | ||
| + | const displayName = name || getDefaultName(); | ||
| + | </ | ||
| + | |||
| + | 这里 '' | ||
| + | |||
| + | 短路特性在实际开发中非常常见。例如: | ||
| + | |||
| + | <code typescript> | ||
| + | isReady && start(); | ||
| + | </ | ||
| + | |||
| + | 这表示:如果 '' | ||
| + | |||
| + | 但是在 TypeScript 中,为了代码可读性,很多团队更推荐写成: | ||
| + | |||
| + | <code typescript> | ||
| + | if (isReady) { | ||
| + | start(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 尤其是在有副作用的函数调用中,显式的 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.10 空值合并二元运算符 ===== | ||
| + | |||
| + | 空值合并运算符是: | ||
| + | |||
| + | <code typescript> | ||
| + | ?? | ||
| + | </ | ||
| + | |||
| + | 它也是一个二元运算符,因为它需要左操作数和右操作数。 | ||
| + | |||
| + | 基本格式如下: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = left ?? right; | ||
| + | </ | ||
| + | |||
| + | 规则是: | ||
| + | |||
| + | * 如果左侧是 '' | ||
| + | * 否则返回左侧 | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const username = null; | ||
| + | const displayName = username ?? " | ||
| + | |||
| + | console.log(displayName); | ||
| + | </ | ||
| + | |||
| + | 如果左侧不是 '' | ||
| + | |||
| + | <code typescript> | ||
| + | const username = ""; | ||
| + | const displayName = username ?? " | ||
| + | |||
| + | console.log(displayName); | ||
| + | </ | ||
| + | |||
| + | 这里结果是空字符串,而不是 ''" | ||
| + | |||
| + | 这正是 ''??'' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.11 ?? 与 || 的区别 ===== | ||
| + | |||
| + | ''??'' | ||
| + | |||
| + | '' | ||
| + | |||
| + | 对比示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = 0 ?? 100; | ||
| + | const b = 0 || 100; | ||
| + | |||
| + | console.log(a); | ||
| + | console.log(b); | ||
| + | </ | ||
| + | |||
| + | 分析: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | 再看空字符串: | ||
| + | |||
| + | <code typescript> | ||
| + | const title1 = "" | ||
| + | const title2 = "" | ||
| + | |||
| + | console.log(title1); | ||
| + | console.log(title2); | ||
| + | </ | ||
| + | |||
| + | 因此,当你希望只有在值“缺失”时才使用默认值,应优先使用 ''??'' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | interface Config { | ||
| + | retryCount?: | ||
| + | } | ||
| + | |||
| + | const config: Config = { | ||
| + | retryCount: 0 | ||
| + | }; | ||
| + | |||
| + | const retryCount = config.retryCount ?? 3; | ||
| + | |||
| + | console.log(retryCount); | ||
| + | </ | ||
| + | |||
| + | 这里用户明确设置了 '' | ||
| + | |||
| + | <code typescript> | ||
| + | const retryCount = config.retryCount || 3; | ||
| + | </ | ||
| + | |||
| + | 结果会变成 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.12 空值合并赋值运算符 ??= ===== | ||
| + | |||
| + | 除了 ''??'' | ||
| + | |||
| + | ''?? | ||
| + | |||
| + | 它的含义是:如果左侧变量当前是 '' | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | let name: string | null = null; | ||
| + | |||
| + | name ??= " | ||
| + | |||
| + | console.log(name); | ||
| + | </ | ||
| + | |||
| + | 如果变量已有值: | ||
| + | |||
| + | <code typescript> | ||
| + | let name = " | ||
| + | |||
| + | name ??= " | ||
| + | |||
| + | console.log(name); | ||
| + | </ | ||
| + | |||
| + | 可以把: | ||
| + | |||
| + | <code typescript> | ||
| + | value ??= defaultValue; | ||
| + | </ | ||
| + | |||
| + | 理解为: | ||
| + | |||
| + | <code typescript> | ||
| + | value = value ?? defaultValue; | ||
| + | </ | ||
| + | |||
| + | 但和其他复合赋值运算符一样,在复杂属性访问场景下,实际求值过程并不完全等同于简单文本替换。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.13 位运算二元运算符 ===== | ||
| + | |||
| + | 位运算符用于按二进制位进行操作。常见的位运算二元运算符包括: | ||
| + | |||
| + | ^ 运算符 ^ 名称 ^ 示例 ^ | ||
| + | | ''&'' | ||
| + | | '' | ||
| + | | '' | ||
| + | | ''<<'' | ||
| + | | ''>>'' | ||
| + | | ''>>>'' | ||
| + | |||
| + | 注意:按位非 '' | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = 5; // 二进制 0101 | ||
| + | const b = 3; // 二进制 0011 | ||
| + | |||
| + | console.log(a & b); // 1,二进制 0001 | ||
| + | console.log(a | b); // 7,二进制 0111 | ||
| + | console.log(a ^ b); // 6,二进制 0110 | ||
| + | </ | ||
| + | |||
| + | 位运算在普通业务代码中不算特别常见,但在以下场景中可能会用到: | ||
| + | |||
| + | * 权限标记 | ||
| + | * 状态压缩 | ||
| + | * 图形处理 | ||
| + | * 加密算法 | ||
| + | * 底层性能优化 | ||
| + | * 网络协议处理 | ||
| + | |||
| + | 例如,用位标记表示权限: | ||
| + | |||
| + | <code typescript> | ||
| + | const READ = 1; // 0001 | ||
| + | const WRITE = 2; // 0010 | ||
| + | const DELETE = 4; // 0100 | ||
| + | |||
| + | let permission = READ | WRITE; | ||
| + | |||
| + | const canRead = (permission & READ) !== 0; | ||
| + | const canDelete = (permission & DELETE) !== 0; | ||
| + | |||
| + | console.log(canRead); | ||
| + | console.log(canDelete); | ||
| + | </ | ||
| + | |||
| + | 这里: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.14 关系二元运算符 ===== | ||
| + | |||
| + | 关系运算符用于判断两个值之间的某种关系。除了前面讲到的大小比较之外,TypeScript 中还常见以下关系运算符: | ||
| + | |||
| + | ^ 运算符 ^ 名称 ^ 示例 ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | ==== 3.14.1 in 运算符 ==== | ||
| + | |||
| + | '' | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const user = { | ||
| + | name: " | ||
| + | age: 18 | ||
| + | }; | ||
| + | |||
| + | console.log(" | ||
| + | console.log(" | ||
| + | </ | ||
| + | |||
| + | 在 TypeScript 中,'' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | type Dog = { | ||
| + | bark: () => void; | ||
| + | }; | ||
| + | |||
| + | type Cat = { | ||
| + | meow: () => void; | ||
| + | }; | ||
| + | |||
| + | function makeSound(animal: | ||
| + | if (" | ||
| + | animal.bark(); | ||
| + | } else { | ||
| + | animal.meow(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 在 '' | ||
| + | |||
| + | ==== 3.14.2 instanceof 运算符 ==== | ||
| + | |||
| + | '' | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | class User { | ||
| + | constructor(public name: string) {} | ||
| + | } | ||
| + | |||
| + | const user = new User(" | ||
| + | |||
| + | console.log(user instanceof User); // true | ||
| + | console.log(user instanceof Date); // false | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code typescript> | ||
| + | function formatValue(value: | ||
| + | if (value instanceof Date) { | ||
| + | return value.toISOString(); | ||
| + | } | ||
| + | |||
| + | return value.toUpperCase(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 在 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.15 类型相关的二元运算注意事项 ===== | ||
| + | |||
| + | TypeScript 的核心优势在于静态类型检查。二元运算符在 TypeScript 中不仅要考虑 JavaScript 的运行时行为,还要考虑编译阶段的类型规则。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const a: number = 10; | ||
| + | const b: string = " | ||
| + | |||
| + | const result = a - b; | ||
| + | </ | ||
| + | |||
| + | 这段代码在 JavaScript 中运行时可能得到 '' | ||
| + | |||
| + | 推荐写法: | ||
| + | |||
| + | <code typescript> | ||
| + | const a: number = 10; | ||
| + | const b: string = " | ||
| + | |||
| + | const result = a - Number(b); | ||
| + | </ | ||
| + | |||
| + | 又如: | ||
| + | |||
| + | <code typescript> | ||
| + | const value: string | undefined = undefined; | ||
| + | |||
| + | const result = value.toUpperCase(); | ||
| + | </ | ||
| + | |||
| + | 如果开启了 '' | ||
| + | |||
| + | 可以使用 ''??'' | ||
| + | |||
| + | <code typescript> | ||
| + | const value: string | undefined = undefined; | ||
| + | |||
| + | const result = (value ?? "" | ||
| + | </ | ||
| + | |||
| + | 也可以使用条件判断: | ||
| + | |||
| + | <code typescript> | ||
| + | if (value !== undefined) { | ||
| + | console.log(value.toUpperCase()); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.16 三元运算符的基本概念 ===== | ||
| + | |||
| + | 三元运算符,英文通常称为 Ternary Operator,是指需要三个操作数的运算符。 | ||
| + | |||
| + | 在 TypeScript 和 JavaScript 中,最常见也几乎是唯一常用的三元运算符是条件运算符: | ||
| + | |||
| + | <code typescript> | ||
| + | condition ? expressionIfTrue : expressionIfFalse | ||
| + | </ | ||
| + | |||
| + | 它也常被称为“条件三元运算符”。 | ||
| + | |||
| + | 结构如下: | ||
| + | |||
| + | <code typescript> | ||
| + | 条件表达式 ? 条件为真时的结果 : 条件为假时的结果 | ||
| + | </ | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const age = 20; | ||
| + | const message = age >= 18 ? " | ||
| + | </ | ||
| + | |||
| + | 这里: | ||
| + | |||
| + | * '' | ||
| + | * ''" | ||
| + | * ''" | ||
| + | * ''?:'' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.17 三元运算符与 if else 的关系 ===== | ||
| + | |||
| + | 三元运算符可以看作是 '' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const age = 20; | ||
| + | |||
| + | let message: string; | ||
| + | |||
| + | if (age >= 18) { | ||
| + | message = " | ||
| + | } else { | ||
| + | message = " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 可以改写为: | ||
| + | |||
| + | <code typescript> | ||
| + | const age = 20; | ||
| + | |||
| + | const message = age >= 18 ? " | ||
| + | </ | ||
| + | |||
| + | 两者的区别是: | ||
| + | |||
| + | * '' | ||
| + | * 三元运算符是表达式,更适合根据条件返回一个值 | ||
| + | |||
| + | 例如,如果只是根据条件决定一个变量的值,三元运算符会比较简洁: | ||
| + | |||
| + | <code typescript> | ||
| + | const buttonText = isLoading ? " | ||
| + | </ | ||
| + | |||
| + | 如果条件分支中有多步操作,则推荐使用 '' | ||
| + | |||
| + | <code typescript> | ||
| + | if (isLoading) { | ||
| + | console.log(" | ||
| + | showSpinner(); | ||
| + | disableButton(); | ||
| + | } else { | ||
| + | console.log(" | ||
| + | hideSpinner(); | ||
| + | enableButton(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 不要为了追求简短而滥用三元运算符。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.18 三元运算符的返回类型推断 ===== | ||
| + | |||
| + | TypeScript 会根据三元运算符两个结果分支推断最终类型。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = true ? 1 : 2; | ||
| + | </ | ||
| + | |||
| + | 这里 '' | ||
| + | |||
| + | 如果两个分支是不同类型: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = Math.random() > 0.5 ? " | ||
| + | </ | ||
| + | |||
| + | 那么 '' | ||
| + | |||
| + | <code typescript> | ||
| + | string | number | ||
| + | </ | ||
| + | |||
| + | 也就是联合类型。 | ||
| + | |||
| + | 再看一个例子: | ||
| + | |||
| + | <code typescript> | ||
| + | const status = isSuccess ? " | ||
| + | </ | ||
| + | |||
| + | 如果 '' | ||
| + | |||
| + | <code typescript> | ||
| + | " | ||
| + | </ | ||
| + | |||
| + | 这在实际开发中非常有用。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | type Status = " | ||
| + | |||
| + | const status: Status = isLoading | ||
| + | ? " | ||
| + | : isSuccess | ||
| + | ? " | ||
| + | : " | ||
| + | </ | ||
| + | |||
| + | 不过上面这个例子使用了嵌套三元运算符,虽然可以工作,但可读性需要谨慎考虑。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.19 嵌套三元运算符 ===== | ||
| + | |||
| + | 三元运算符可以嵌套使用,但不推荐过度嵌套。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const score = 85; | ||
| + | |||
| + | const level = score >= 90 | ||
| + | ? " | ||
| + | : score >= 60 | ||
| + | ? " | ||
| + | : " | ||
| + | </ | ||
| + | |||
| + | 这段代码的含义是: | ||
| + | |||
| + | * 如果 '' | ||
| + | * 否则继续判断 '' | ||
| + | * 如果 '' | ||
| + | * 否则结果是 ''" | ||
| + | |||
| + | 虽然这段代码不长,但如果条件继续增加,就会变得难以阅读。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const label = type === " | ||
| + | ? " | ||
| + | : type === " | ||
| + | ? " | ||
| + | : type === " | ||
| + | ? " | ||
| + | : type === " | ||
| + | ? " | ||
| + | : " | ||
| + | </ | ||
| + | |||
| + | 这种写法虽然合法,但可读性较差。 | ||
| + | |||
| + | 更推荐使用对象映射或 '' | ||
| + | |||
| + | <code typescript> | ||
| + | const labels: Record< | ||
| + | admin: " | ||
| + | editor: " | ||
| + | guest: " | ||
| + | anonymous: " | ||
| + | }; | ||
| + | |||
| + | const label = labels[type] ?? " | ||
| + | </ | ||
| + | |||
| + | 或者: | ||
| + | |||
| + | <code typescript> | ||
| + | let label: string; | ||
| + | |||
| + | switch (type) { | ||
| + | case " | ||
| + | label = " | ||
| + | break; | ||
| + | case " | ||
| + | label = " | ||
| + | break; | ||
| + | case " | ||
| + | label = " | ||
| + | break; | ||
| + | case " | ||
| + | label = " | ||
| + | break; | ||
| + | default: | ||
| + | label = " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 原则是:三元运算符适合简单条件,复杂分支应使用更清晰的结构。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.20 三元运算符在 JSX 和模板中的使用 ===== | ||
| + | |||
| + | 在 React 或其他模板场景中,三元运算符非常常见。 | ||
| + | |||
| + | 例如 React JSX 中: | ||
| + | |||
| + | <code tsx> | ||
| + | function Button({ isLoading }: { isLoading: boolean }) { | ||
| + | return ( | ||
| + | < | ||
| + | {isLoading ? " | ||
| + | </ | ||
| + | ); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 再例如根据用户状态显示不同内容: | ||
| + | |||
| + | <code tsx> | ||
| + | function UserPanel({ isLoggedIn }: { isLoggedIn: boolean }) { | ||
| + | return ( | ||
| + | <div> | ||
| + | {isLoggedIn ? < | ||
| + | </ | ||
| + | ); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 在 JSX 中,三元运算符比 '' | ||
| + | |||
| + | 但是,如果条件逻辑复杂,建议提前在函数体中计算好结果: | ||
| + | |||
| + | <code tsx> | ||
| + | function StatusText({ status }: { status: " | ||
| + | let text: string; | ||
| + | |||
| + | if (status === " | ||
| + | text = " | ||
| + | } else if (status === " | ||
| + | text = " | ||
| + | } else { | ||
| + | text = " | ||
| + | } | ||
| + | |||
| + | return < | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 这样 JSX 部分会更清晰。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.21 三元运算符与空值合并运算符的组合 ===== | ||
| + | |||
| + | 三元运算符经常和 ''??'' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const displayName = user.name ?? " | ||
| + | </ | ||
| + | |||
| + | 如果逻辑更复杂: | ||
| + | |||
| + | <code typescript> | ||
| + | const displayName = user.name | ||
| + | ? user.name | ||
| + | : user.nickname ?? " | ||
| + | </ | ||
| + | |||
| + | 这里的逻辑是: | ||
| + | |||
| + | * 如果 '' | ||
| + | * 否则尝试使用 '' | ||
| + | * 如果 '' | ||
| + | |||
| + | 但要注意,'' | ||
| + | |||
| + | <code typescript> | ||
| + | const displayName = user.name ?? user.nickname ?? " | ||
| + | </ | ||
| + | |||
| + | 这表示只有当前一个值为 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.22 运算符优先级简介 ===== | ||
| + | |||
| + | 当一个表达式中出现多个运算符时,运算符优先级决定了先执行哪个。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = 1 + 2 * 3; | ||
| + | </ | ||
| + | |||
| + | 结果是 '' | ||
| + | |||
| + | 如果希望先执行加法,可以使用括号: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = (1 + 2) * 3; | ||
| + | </ | ||
| + | |||
| + | 这时结果是 '' | ||
| + | |||
| + | 在实际开发中,不建议过度依赖记忆运算符优先级。对于稍复杂的表达式,推荐使用括号明确表达意图。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = a && b || c; | ||
| + | </ | ||
| + | |||
| + | 可以改写为: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = (a && b) || c; | ||
| + | </ | ||
| + | |||
| + | 或者: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = a && (b || c); | ||
| + | </ | ||
| + | |||
| + | 根据实际需求明确分组。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.23 ?? 与 && | ||
| + | |||
| + | 空值合并运算符 ''??'' | ||
| + | |||
| + | 在 JavaScript 和 TypeScript 中,不能在没有括号的情况下直接混用 ''??'' | ||
| + | |||
| + | 例如下面的写法是错误的: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = a ?? b || c; | ||
| + | </ | ||
| + | |||
| + | 应该使用括号明确优先级: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = (a ?? b) || c; | ||
| + | </ | ||
| + | |||
| + | 或者: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = a ?? (b || c); | ||
| + | </ | ||
| + | |||
| + | 这两种写法含义不同。 | ||
| + | |||
| + | 第一种: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = (a ?? b) || c; | ||
| + | </ | ||
| + | |||
| + | 表示先判断 '' | ||
| + | |||
| + | 第二种: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = a ?? (b || c); | ||
| + | </ | ||
| + | |||
| + | 表示如果 '' | ||
| + | |||
| + | 示例: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = 0; | ||
| + | const b = " | ||
| + | const c = " | ||
| + | |||
| + | const value1 = (a ?? b) || c; | ||
| + | const value2 = a ?? (b || c); | ||
| + | |||
| + | console.log(value1); | ||
| + | console.log(value2); | ||
| + | </ | ||
| + | |||
| + | 分析: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | 因此混用这些运算符时,必须认真使用括号。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.24 二元运算符和三元运算符的可读性原则 ===== | ||
| + | |||
| + | 运算符虽然可以让代码更简洁,但并不意味着越短越好。 | ||
| + | |||
| + | 推荐原则如下: | ||
| + | |||
| + | * 简单表达式可以使用运算符 | ||
| + | * 复杂逻辑不要强行压缩到一行 | ||
| + | * 涉及多个运算符时优先使用括号 | ||
| + | * 三元运算符适合“二选一”赋值 | ||
| + | * 嵌套三元运算符要谨慎使用 | ||
| + | * 对默认值处理优先考虑 ''??'' | ||
| + | * 对布尔条件组合要注意短路行为 | ||
| + | * 对数字和字符串混合运算要避免隐式转换 | ||
| + | |||
| + | 例如,不推荐: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = a ? b ? c : d : e ? f : g; | ||
| + | </ | ||
| + | |||
| + | 更推荐: | ||
| + | |||
| + | <code typescript> | ||
| + | let result: string; | ||
| + | |||
| + | if (a) { | ||
| + | result = b ? c : d; | ||
| + | } else { | ||
| + | result = e ? f : g; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 虽然代码行数更多,但逻辑更清晰。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.25 实际开发示例:默认配置 ===== | ||
| + | |||
| + | 假设有一个配置对象: | ||
| + | |||
| + | <code typescript> | ||
| + | interface Options { | ||
| + | timeout?: number; | ||
| + | retry?: number; | ||
| + | debug?: boolean; | ||
| + | } | ||
| + | |||
| + | function createOptions(options: | ||
| + | const timeout = options.timeout ?? 3000; | ||
| + | const retry = options.retry ?? 3; | ||
| + | const debug = options.debug ?? false; | ||
| + | |||
| + | return { | ||
| + | timeout, | ||
| + | retry, | ||
| + | debug | ||
| + | }; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 这里使用 ''??'' | ||
| + | |||
| + | 因为以下配置是有意义的: | ||
| + | |||
| + | <code typescript> | ||
| + | createOptions({ | ||
| + | timeout: 0, | ||
| + | retry: 0, | ||
| + | debug: false | ||
| + | }); | ||
| + | </ | ||
| + | |||
| + | 如果使用 '' | ||
| + | |||
| + | <code typescript> | ||
| + | const timeout = options.timeout || 3000; | ||
| + | const retry = options.retry || 3; | ||
| + | const debug = options.debug || false; | ||
| + | </ | ||
| + | |||
| + | 那么 '' | ||
| + | |||
| + | 使用 ''??'' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.26 实际开发示例:状态显示 ===== | ||
| + | |||
| + | 假设一个请求状态可能是: | ||
| + | |||
| + | <code typescript> | ||
| + | type RequestStatus = " | ||
| + | </ | ||
| + | |||
| + | 可以用三元运算符显示文字: | ||
| + | |||
| + | <code typescript> | ||
| + | function getStatusText(status: | ||
| + | return status === " | ||
| + | ? " | ||
| + | : status === " | ||
| + | ? " | ||
| + | : status === " | ||
| + | ? " | ||
| + | : " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 虽然这段代码可以正常工作,但嵌套三元较多。 | ||
| + | |||
| + | 更推荐: | ||
| + | |||
| + | <code typescript> | ||
| + | function getStatusText(status: | ||
| + | const map: Record< | ||
| + | idle: " | ||
| + | loading: " | ||
| + | success: " | ||
| + | error: " | ||
| + | }; | ||
| + | |||
| + | return map[status]; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 如果状态值可能来自外部字符串: | ||
| + | |||
| + | <code typescript> | ||
| + | function getStatusText(status: | ||
| + | const map: Record< | ||
| + | idle: " | ||
| + | loading: " | ||
| + | success: " | ||
| + | error: " | ||
| + | }; | ||
| + | |||
| + | return map[status] ?? " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 这里 ''??'' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.27 实际开发示例:表单校验 ===== | ||
| + | |||
| + | 二元运算符和三元运算符在表单校验中非常常见。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | function validateUsername(username: | ||
| + | return username.length >= 3 ? "" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 如果有多个条件: | ||
| + | |||
| + | <code typescript> | ||
| + | function validatePassword(password: | ||
| + | if (password.length < 8) { | ||
| + | return " | ||
| + | } | ||
| + | |||
| + | if (!/ | ||
| + | return " | ||
| + | } | ||
| + | |||
| + | if (!/ | ||
| + | return " | ||
| + | } | ||
| + | |||
| + | return ""; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 这里不建议写成复杂嵌套三元: | ||
| + | |||
| + | <code typescript> | ||
| + | function validatePassword(password: | ||
| + | return password.length < 8 | ||
| + | ? " | ||
| + | : !/ | ||
| + | ? " | ||
| + | : !/ | ||
| + | ? " | ||
| + | : ""; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 虽然它是合法的,但可读性不如多个 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.28 实际开发示例:权限判断 ===== | ||
| + | |||
| + | 权限判断中常用逻辑二元运算符。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | interface User { | ||
| + | role: " | ||
| + | active: boolean; | ||
| + | } | ||
| + | |||
| + | function canEdit(user: | ||
| + | return user.active && (user.role === " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 这里: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * 括号用于明确逻辑组合关系 | ||
| + | |||
| + | 如果不用括号: | ||
| + | |||
| + | <code typescript> | ||
| + | return user.active && user.role === " | ||
| + | </ | ||
| + | |||
| + | 虽然按照优先级也能执行,但可读性不如带括号的版本,而且容易让读者误解。 | ||
| + | |||
| + | 更清晰的写法: | ||
| + | |||
| + | <code typescript> | ||
| + | function canEdit(user: | ||
| + | const isActive = user.active; | ||
| + | const hasRole = user.role === " | ||
| + | |||
| + | return isActive && hasRole; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 这种写法在复杂业务逻辑中更容易维护。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.29 常见错误一:把 || 当作默认值处理的一切方案 ===== | ||
| + | |||
| + | 很多初学者会这样写: | ||
| + | |||
| + | <code typescript> | ||
| + | const pageSize = inputPageSize || 20; | ||
| + | </ | ||
| + | |||
| + | 这在某些场景下没有问题,但如果 '' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const inputPageSize = 0; | ||
| + | const pageSize = inputPageSize || 20; | ||
| + | |||
| + | console.log(pageSize); | ||
| + | </ | ||
| + | |||
| + | 如果 '' | ||
| + | |||
| + | 更推荐: | ||
| + | |||
| + | <code typescript> | ||
| + | const pageSize = inputPageSize ?? 20; | ||
| + | </ | ||
| + | |||
| + | 这样只有当 '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.30 常见错误二:三元运算符嵌套过深 ===== | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = a | ||
| + | ? b | ||
| + | ? c | ||
| + | : d | ||
| + | : e | ||
| + | ? f | ||
| + | : g; | ||
| + | </ | ||
| + | |||
| + | 这类代码虽然简短,但阅读成本较高。 | ||
| + | |||
| + | 建议改写为 '' | ||
| + | |||
| + | <code typescript> | ||
| + | let result; | ||
| + | |||
| + | if (a) { | ||
| + | if (b) { | ||
| + | result = c; | ||
| + | } else { | ||
| + | result = d; | ||
| + | } | ||
| + | } else { | ||
| + | if (e) { | ||
| + | result = f; | ||
| + | } else { | ||
| + | result = g; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 或者根据业务场景抽成函数: | ||
| + | |||
| + | <code typescript> | ||
| + | function getResult() { | ||
| + | if (a && b) { | ||
| + | return c; | ||
| + | } | ||
| + | |||
| + | if (a && !b) { | ||
| + | return d; | ||
| + | } | ||
| + | |||
| + | if (!a && e) { | ||
| + | return f; | ||
| + | } | ||
| + | |||
| + | return g; | ||
| + | } | ||
| + | |||
| + | const result = getResult(); | ||
| + | </ | ||
| + | |||
| + | 函数化往往能让复杂条件更容易测试和维护。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.31 常见错误三:忽略 TypeScript 的联合类型 ===== | ||
| + | |||
| + | 三元运算符可能产生联合类型。 | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = condition ? " | ||
| + | </ | ||
| + | |||
| + | 此时 '' | ||
| + | |||
| + | <code typescript> | ||
| + | string | number | ||
| + | </ | ||
| + | |||
| + | 如果后续直接调用字符串方法: | ||
| + | |||
| + | <code typescript> | ||
| + | console.log(value.toUpperCase()); | ||
| + | </ | ||
| + | |||
| + | TypeScript 会报错,因为 '' | ||
| + | |||
| + | 正确做法是先进行类型判断: | ||
| + | |||
| + | <code typescript> | ||
| + | if (typeof value === " | ||
| + | console.log(value.toUpperCase()); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 或者保证三元表达式两个分支返回同一种类型: | ||
| + | |||
| + | <code typescript> | ||
| + | const value = condition ? " | ||
| + | console.log(value.toUpperCase()); | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.32 常见错误四:误解 && 和 || 的返回值 ===== | ||
| + | |||
| + | 很多人以为 ''&&'' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = " | ||
| + | console.log(result); | ||
| + | </ | ||
| + | |||
| + | 再比如: | ||
| + | |||
| + | <code typescript> | ||
| + | const result = "" | ||
| + | console.log(result); | ||
| + | </ | ||
| + | |||
| + | 如果你需要明确得到布尔值,可以使用 '' | ||
| + | |||
| + | <code typescript> | ||
| + | const value = " | ||
| + | |||
| + | const bool1 = Boolean(value); | ||
| + | const bool2 = !!value; | ||
| + | </ | ||
| + | |||
| + | 在 TypeScript 中,清楚区分“返回某个值”和“返回布尔值”非常重要。 | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.33 常见错误五:对象比较使用 === 判断内容相等 ===== | ||
| + | |||
| + | 比较运算符 '' | ||
| + | |||
| + | 例如: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = { name: " | ||
| + | const b = { name: " | ||
| + | |||
| + | console.log(a === b); // false | ||
| + | </ | ||
| + | |||
| + | 虽然两个对象内容看起来一样,但它们是两个不同对象。 | ||
| + | |||
| + | 如果是同一个引用: | ||
| + | |||
| + | <code typescript> | ||
| + | const a = { name: " | ||
| + | const b = a; | ||
| + | |||
| + | console.log(a === b); // true | ||
| + | </ | ||
| + | |||
| + | 数组也是一样: | ||
| + | |||
| + | <code typescript> | ||
| + | console.log([1, | ||
| + | </ | ||
| + | |||
| + | 如果需要比较内容,需要自己逐项比较,或者使用专门的工具函数。 | ||
| + | |||
| + | 简单数组比较示例: | ||
| + | |||
| + | <code typescript> | ||
| + | function isSameNumberArray(a: | ||
| + | if (a.length !== b.length) { | ||
| + | return false; | ||
| + | } | ||
| + | |||
| + | return a.every((item, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 3.34 本章小结 ===== | ||
| + | |||
| + | 本章详细介绍了 TypeScript 中的二元运算符与三元运算符。 | ||
| + | |||
| + | 二元运算符是需要两个操作数的运算符,例如: | ||
| + | |||
| + | <code typescript> | ||
| + | a + b | ||
| + | a === b | ||
| + | a && b | ||
| + | a ?? b | ||
| + | </ | ||
| + | |||
| + | 常见二元运算符包括: | ||
| + | |||
| + | * 算术运算符 | ||
| + | * 赋值运算符 | ||
| + | * 比较运算符 | ||
| + | * 逻辑运算符 | ||
| + | * 空值合并运算符 | ||
| + | * 位运算符 | ||
| + | * 关系运算符 | ||
| + | |||
| + | 三元运算符是需要三个操作数的运算符。TypeScript 中最常见的三元运算符是条件运算符: | ||
| + | |||
| + | <code typescript> | ||
| + | condition ? valueIfTrue : valueIfFalse | ||
| + | </ | ||
| + | |||
| + | 它适合根据条件选择一个值,但不适合承载过于复杂的业务逻辑。 | ||
| + | |||
| + | 在实际开发中,应特别注意以下几点: | ||
| + | |||
| + | * ''??'' | ||
| + | * ''??'' | ||
| + | * '' | ||
| + | * ''&&'' | ||
| + | * 三元运算符适合简单二选一 | ||
| + | * 嵌套三元运算符要谨慎使用 | ||
| + | * 比较对象时,'' | ||
| + | * 复杂表达式建议使用括号提高可读性 | ||
| + | * TypeScript 会根据运算符推断表达式类型 | ||
| + | * 当三元运算符两个分支类型不同,结果通常是联合类型 | ||
| + | |||
| + | 理解这些规则之后,就能更准确地阅读和编写 TypeScript 表达式,也能避免许多由隐式类型转换、默认值处理、逻辑短路和类型推断造成的常见错误。 | ||