TypeScript 流程控制与运算符
📚 TypeScript 教程系列
⚠️ 来源声明:本文内容参考自 菜鸟教程 TypeScript 教程,仅供学习交流,版权归原作者所有。
TypeScript 在 JavaScript 之上补充了类型系统,而运算符、条件语句、循环以及迭代器/生成器构成了程序流程控制的核心。本篇将这几部分串联起来,覆盖从算术运算到生成器惰性求值的完整链路,帮助你在类型约束下写出更清晰的控制流。
运算符
运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。例如 7 + 5 = 12 中,7、5、12 是操作数,+ 是加法运算符,= 是赋值运算符。
TypeScript 常用运算符包括:算术运算符、关系运算符、逻辑运算符、按位运算符、赋值运算符、三元/条件运算符、字符串运算符以及类型运算符。
算术运算符
假定 y = 5,下表列出了 TypeScript 支持的算术运算符:
| 运算符 | 描述 | 例子 | x 运算结果 | y 运算结果 |
|---|---|---|---|---|
| + | 加法 | x = y + 2 | 7 | 5 |
| - | 减法 | x = y - 2 | 3 | 5 |
| * | 乘法 | x = y * 2 | 10 | 5 |
| / | 除法 | x = y / 2 | 2.5 | 5 |
| % | 取模(余数) | x = y % 2 | 1 | 5 |
| ++ | 自增 | x = ++y | 6 | 6 |
| ++ | 自增 | x = y++ | 5 | 6 |
| – | 自减 | x = --y | 4 | 4 |
| – | 自减 | x = y– | 5 | 4 |
实例:
1 | |
输出结果:
1 | |
关系运算符
关系运算符用于计算结果是否为 true 或者 false。假定 x = 5,下表说明了各关系运算符的运算结果:
| 运算符 | 描述 | 比较 | 返回值 |
|---|---|---|---|
| == | 等于 | x == 8 | false |
| == | 等于 | x == 5 | true |
| != | 不等于 | x != 8 | true |
| > | 大于 | x > 8 | false |
| < | 小于 | x < 8 | true |
| >= | 大于或等于 | x >= 8 | false |
| <= | 小于或等于 | x <= 8 | true |
实例:
1 | |
输出结果:
1 | |
逻辑运算符
假定 x = 6、y = 3,下表列出了 TypeScript 支持的逻辑运算符:
| 运算符 | 描述 | 例子 |
|---|---|---|
| && | and | (x < 10 && y > 1) 为 true |
| || | or | (x == 5 || y == 5) 为 false |
| ! | not | !(x == y) 为 true |
实例:
1 | |
输出结果:
1 | |
短路运算符(&& 与 ||)
&&运算符:如果第一个操作数为false,就不再执行后面的判断,直接返回false。例如a > 5为false时,后续表达式会被跳过计算。||运算符:如果第一个操作数为true,就不再执行后面的判断,直接返回true。例如a < 10为true时,后续表达式会被跳过计算。
位运算符
位运算符作用于操作数的二进制位。下表假设变量 a = 5(二进制 0101)、b = 1(二进制 0001):
| 运算符 | 描述 | 例子 | 类似于 | 结果 | 十进制 |
|---|---|---|---|---|---|
| & | AND | x = 5 & 1 | 0101 & 0001 | 0001 | 1 |
| | | OR | x = 5 | 1 | 0101 | 0001 | 0101 | 5 |
| ~ | 取反 | x = ~5 | ~0101 | 1010 | -6 |
| ^ | 异或 | x = 5 ^ 1 | 0101 ^ 0001 | 0100 | 4 |
| << | 左移 | x = 5 << 1 | 0101 << 1 | 1010 | 10 |
| >> | 右移 | x = 5 >> 1 | 0101 >> 1 | 0010 | 2 |
| >>> | 无符号右移 | x = 2 >>> 1 | 0010 >>> 1 | 0001 | 1 |
实例:
1 | |
输出结果:
1 | |
赋值运算符
假定 x = 10、y = 5,下表列出了赋值运算符:
| 运算符 | 例子 | 实例 | x 值 |
|---|---|---|---|
| = (赋值) | x = y | x = y | x = 5 |
| += | x += y | x = x + y | x = 15 |
| -= | x -= y | x = x - y | x = 5 |
| *= | x *= y | x = x * y | x = 50 |
| /= | x /= y | x = x / y | x = 2 |
类似的逻辑运算符也可以与赋值运算符联合使用:<<=、>>=、>>>=、&=、|= 与 ^=。
实例:
1 | |
输出结果:
1 | |
三元运算符(?)
三元运算符语法格式:
1 | |
Test:指定的条件语句。expr1:如果Test为true则返回该值。expr2:如果Test为false则返回该值。
实例:
1 | |
输出结果:
1 | |
类型运算符
typeof 运算符
typeof 是一元运算符,返回操作数的数据类型。
1 | |
输出结果:
1 | |
instanceof 运算符
instanceof 运算符用于判断对象是否为指定的类型。
其他运算符
负号运算符(-)
负号运算符用于更改操作数的符号。
1 | |
输出结果:
1 | |
字符串运算符:连接运算符(+)
+ 运算符可以拼接两个字符串。
1 | |
输出结果:
1 | |
条件语句
条件语句用于基于不同的条件来执行不同的动作。TypeScript 条件语句是通过一条或多条语句的执行结果(true 或 false)来决定执行的代码块。

通常在写代码时,总是需要为不同的决定来执行不同的动作,可以在代码中使用条件语句来完成该任务。在 TypeScript 中,可使用以下条件语句:
- if 语句:只有当指定条件为
true时,使用该语句来执行代码。 - if…else 语句:当条件为
true时执行代码,当条件为false时执行其他代码。 - if…else if…else 语句:使用该语句来选择多个代码块之一来执行。
- switch 语句:使用该语句来选择多个代码块之一来执行。
if 语句
TypeScript if 语句由一个布尔表达式后跟一个或多个语句组成。
语法
1 | |
如果布尔表达式 boolean_expression 为 true,则 if 语句内的代码块将被执行。如果布尔表达式为 false,则 if 语句结束后的第一组代码(闭括号后)将被执行。

实例
1 | |
编译以上代码得到如下 JavaScript 代码:
1 | |
执行以上代码,输出结果为:
1 | |
if…else 语句
一个 if 语句后可跟一个可选的 else 语句,else 语句在布尔表达式为 false 时执行。
语法
1 | |
如果布尔表达式为 true,则执行 if 块内的代码;如果布尔表达式为 false,则执行 else 块内的代码。

实例
1 | |
编译后得到的 JavaScript 代码:
1 | |
输出结果:
1 | |
if…else if…else 语句
if...else if...else 语句在执行多个判断条件的时候很有用。
语法
1 | |
需要注意以下几点:
- 一个
if判断语句可以有 0 或 1 个else语句,它必须放在else if语句后面。 - 一个
if判断语句可以有 0 或多个else if,这些语句必须放在else之前。 - 一旦执行了某个
else if内的代码,后面的else if或else将不再执行。
实例
1 | |
编译后得到的 JavaScript 代码:
1 | |
输出结果:
1 | |
switch…case 语句
一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 case 进行检查。
语法
1 | |
switch 语句必须遵循下面的规则:
switch语句中的expression是一个要被比较的表达式,可以是任何类型,包括基本数据类型(如number、string、boolean)、对象类型(如object、Array、Map)以及自定义类型(如class、interface、enum)等。- 在一个
switch中可以有任意数量的case语句。每个case后跟一个要比较的值和一个冒号。 case的constant-expression必须与switch中的变量expression具有相同或兼容的数据类型。- 当被测试的变量等于
case中的常量时,case后跟的语句将被执行,直到遇到break语句为止。 - 当遇到
break语句时,switch终止,控制流将跳转到switch语句后的下一行。 - 不是每一个
case都需要包含break。如果case语句不包含break,控制流将会继续后续的case,直到遇到break为止。 - 一个
switch语句可以有一个可选的default case,出现在switch的结尾。default关键字表示当表达式的值与所有case值都不匹配时执行的代码块。default case中的break语句不是必需的。

实例
1 | |
编译后得到的 JavaScript 代码:
1 | |
输出结果:
1 | |
循环
有的时候,我们可能需要多次执行同一块代码。一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推。编程语言提供了更为复杂执行路径的多种控制结构,循环语句允许我们多次执行一个语句或语句组。

for 循环
TypeScript for 循环用于多次执行一个语句序列,简化管理循环变量的代码。
语法
1 | |
for 循环的控制流程解析:
init会首先被执行,且只会执行一次。这一步允许你声明并初始化任何循环控制变量。你也可以不在这里写任何语句,只要有一个分号出现即可。- 接下来,会判断
condition。如果为true,则执行循环主体;如果为false,则不执行循环主体,且控制流会跳转到紧接着for循环的下一条语句。 - 在执行完
for循环主体后,控制流会跳回上面的increment语句。该语句允许你更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。 - 条件再次被判断。如果为
true,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为false时,for循环终止。
其中 statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。condition 可以是任意的表达式,当条件为 true 时执行循环,当条件为 false 时退出循环。

实例
以下实例计算 5 的阶乘,for 循环生成从 5 到 1 的数字,并计算每次循环数字的乘积。
1 | |
编译后得到的 JavaScript 代码:
1 | |
输出结果:
1 | |
for…in 循环
for...in 语句用于一组值的集合或列表进行迭代输出。
语法
1 | |
val 需要为 string 或 any 类型。
实例
1 | |
编译后的 JavaScript 代码:
1 | |
输出结果:
1 | |
for…of、forEach、every 和 some 循环
此外,TypeScript 还支持 for...of、forEach、every 和 some 循环。for...of 语句创建一个循环来迭代可迭代的对象,在 ES6 中引入的 for...of 循环用于替代 for...in 和 forEach(),并支持新的迭代协议。for...of 允许你遍历 Arrays(数组)、Strings(字符串)、Maps(映射)、Sets(集合)等可迭代的数据结构。
TypeScript for…of 循环
1 | |
forEach、every 和 some 是 JavaScript 的循环语法,TypeScript 作为 JavaScript 的语法超集,当然默认也是支持的。因为 forEach 在 iteration 中是无法返回的,所以可以使用 every 和 some 来取代 forEach。
TypeScript forEach 循环
1 | |
TypeScript every 循环
1 | |
while 循环
while 语句在给定条件为 true 时,重复执行语句或语句组。循环主体执行之前会先测试条件。
语法
1 | |
statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。condition 可以是任意的表达式,当条件为 true 时执行循环;当条件为 false 时,程序流将退出循环。

while 循环的关键点是循环可能一次都不会执行。当条件为 false 时,会跳过循环主体,直接执行紧接着 while 循环的下一条语句。
实例
1 | |
编译后的 JavaScript 代码:
1 | |
输出结果:
1 | |
do…while 循环
不像 for 和 while 循环它们是在循环头部测试循环条件,do...while 循环是在循环的尾部检查它的条件。
语法
1 | |
请注意,条件表达式出现在循环的尾部,所以循环中的 statement(s) 会在条件被测试之前至少执行一次。如果条件为 true,控制流会跳转回上面的 do,然后重新执行循环中的 statement(s)。这个过程会不断重复,直到给定条件变为 false 为止。

实例
1 | |
编译后的 JavaScript 代码:
1 | |
输出结果:
1 | |
break 语句
break 语句有以下两种用法:
- 当
break语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。 - 它可用于终止
switch语句中的一个case。
如果你使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。
语法
1 | |

实例
1 | |
编译后的 JavaScript 代码:
1 | |
输出结果:
1 | |
continue 语句
continue 语句有点像 break 语句。但它不是强制终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。
对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 while 和 do...while 循环,continue 语句重新执行条件判断语句。
语法
1 | |

实例
1 | |
编译后的 JavaScript 代码:
1 | |
输出结果:
1 | |
无限循环
无限循环就是一直在运行不会停止的循环。for 和 while 循环都可以创建无限循环。
for 创建无限循环语法格式:
1 | |
实例:
1 | |
while 创建无限循环语法格式:
1 | |
实例:
1 | |
迭代器与生成器
迭代器和生成器是处理集合的关键模式。迭代器提供了一个统一的 next() 方法用于遍历数据,生成器则是一种特殊的函数,能够在执行过程中暂停并返回值,让处理大数据流、无限序列等变得更加简单。
为什么需要迭代器与生成器
在处理集合数据时,我们常常需要遍历数组、对象等。迭代器提供了统一的、可定制的遍历接口;生成器则提供了一种简洁的方式来创建迭代器——使用可以暂停和恢复执行的函数。
- 迭代器是一个对象,它提供
next()方法用于遍历数据。 - 生成器是一种特殊的函数,可以在执行过程中暂停并返回一个值。
可迭代协议(Iterable Protocol)
实现了 Symbol.iterator 的对象可以通过 for...of 来遍历。数组和字符串都内置实现了 Symbol.iterator 方法,所以可以直接使用 for...of 遍历。
1 | |
输出结果:
1 | |
自定义可迭代对象
通过实现 Symbol.iterator,可以让一个普通对象变得可遍历。迭代器协议要求迭代器必须有一个 next() 方法,返回 { done: boolean, value: any } 格式的对象。
1 | |
输出结果:
1 | |
生成器函数
使用 function* 语法定义生成器函数,配合 yield 可以暂停执行并返回值。生成器函数会返回一个迭代器,每次调用 next() 都会执行到下一个 yield 语句。
1 | |
输出结果:
1 | |
无限生成器
生成器可以借助惰性求值产生无限序列,而不会消耗无限内存。生成器的最大优势是惰性求值——只有在调用 next() 时才会计算下一个值,非常适合处理无限序列。
1 | |
输出结果:
1 | |
委托生成器
使用 yield* 可以将生成操作委托给另一个生成器或可迭代对象。yield* 可以组合多个生成器或可迭代对象,非常适合构建可复用的数据流。
1 | |
输出结果:
1 | |
TypeScript 生成器类型
在 TypeScript 中,生成器可以使用 Generator 类型进行标注。Generator<T, R, N> 表示:
T是yield返回值的类型。R是生成器最终返回的类型。N是next()方法接收参数的类型。
1 | |
输出结果:
1 | |
迭代器与生成器要点
- 迭代器协议:实现
Symbol.iterator,返回一个带next()方法的对象。 - 生成器语法:使用
function*而不是function。 yield关键字:暂停执行并返回一个值。- 惰性求值:生成器按需计算下一个值。
最佳实践:在需要遍历自定义对象、处理大数据流、创建无限序列或需要暂停/恢复的场景下,优先考虑使用迭代器与生成器。可迭代对象实现 Symbol.iterator 接口,生成器使用 function* 和 yield 创建,委托则使用 yield* 组合多个生成器。

