目录
[for...of / forEach / every / some](#for...of / forEach / every / some)
[注意 :无限循环](#注意 :无限循环)
在写代码的时候,有时候我们只是想让某一句话、多行逻辑......重复地执行。就像你对朋友说一句话:"大家来一下",然后让大家一个一个做同样的事。
普通代码是"从上往下走,一条一条地执行"。可当你想让同一段代码 "多次" 执行------这时候,就需要一种机制,这种机制就是"循环"。用循环,你可以远离"复制粘贴",让代码变得干净、优雅、有节奏。
常见的循环方式
在TypeScript/JavaScript里,有好几种循环,每一种都有自己的"性格"。搞清楚它们,就好像你识得各种乐器该什么时候上场。
传统的for循环
以次数决定成败
TypeScriptfor (init; condition; increment) { // ...要反复执行的代码... }
- init:通常是设定初始值,比如i=0,只执行一次
- condition:循环继续的条件,只要为True,循环就继续
- increment:每完成一次循环后,对控制变量继续更新(比如i)
这样,你可以控制"从0到9,一共十次" ------ 非常适合"你明确知道应该循环多少次"的场景。
例如,
TypeScript
let num = 5;
let factorial = 1;
for (let i = num; i >= 1; i--) {
factorial *= i;
}
console.log(factorial); // 输出 120
这段代码,用for从5开始,一直乘到1,就算出了5的阶乘。
就像你在做手工任务------ "从第5个,到第4个,到第3个 ... 一直到第1个",每一步都在控制。
for...in
以"属性 / 索引 / 键名"之名
for...in是另一种循环,适合用来遍历一个"集合 / 列表 / 对象"里每一项的"索引或键名"。换句话说,它告诉你"第几个 / 属性名是什么",然后你可以用这个索引/键名取出对应值。
例如,
TypeScript
let str = "a b c";
for (let j in str) {
console.log(str[j]); // 逐个输出 a, 空格, b, 空格, c
}
这个例子中,用in遍历字符串,就像问字符串"你第 0 个字符是? 第 1 个字符是?......"然后依次输出。
不过要注意:如果你只是想遍历"值"而不是"索引 / 键",for...in往往不是最合适的。
for...of / forEach / every / some
更现代,更方便
随着 ES6 的普及,for...of 就像新时代的循环方式。它的美在于:你不再关心"索引 / 键名是什么",你只关心"值是什么"。对于数组 (Array)、字符串 (String)、集合 (Set)、映射 (Map)......所有"可迭代 (iterable)"的数据结构都适用。
TypeScript
let someArray = [1, "hello", false];
for (let entry of someArray) {
console.log(entry);
}
// 输出 1, "hello", false
相较于for、for...in,for...of更简洁、更直观。如果你只是相对每一个元素做同样的操作(比如打印、累加、判断...),它是一把非常顺手、干净的利器。
另外,像forEach,every,some这些方法,也是常见的"现代JS/TS循环风格"。不过根据官方教程,forEach在循环内部不容易"跳出/返回(return)"------如果你需要***"中断/退出/判断"的话,有时every或some***会更合适。
while和do...while
只管条件不论次数
- while(conditiion){...}:
- 只要condition为真,就不断执行循环体。进入循环之前就判断条件,所以有可能一次都不执行。
- do{...}while(condition);:
- 先执行一次循环体,然后判断条件。如果为真,就继续下一轮,即至少执行一次。
这种类型的循环适合用于"直到某个条件达成为止"的情境 ------ 比如不断读取用户输入、不断等待某个状态改变,或者执行未知次数但有终止条件的任务。
break与continue
奇变偶不变
有时候,你在循环里,不想继续当前循环,也不想继续所有循环,这时候就用它们:
- break:
- 一旦执行,立即跳出当前循环(或break所在的最内层循环),不再继续。
- continue:
- 跳过本次循环里剩下的语句,直接进入下一轮
- 对于for循环:会执行【自增/更新步骤】
- 对于while/do...while:会重新【判断条件】
- 跳过本次循环里剩下的语句,直接进入下一轮
例如,当需要从1-10中找到第一个被5整除的数:
TypeScript
let i = 1;
while (i <= 10) {
if (i % 5 == 0) {
console.log("第一个被 5 整除的是:", i);
break;
}
i++;
}
一旦找到,就通过break跳出循环。
注意 :无限循环
设法剪断套住树苗的绳索
在for循环中:
TypeScript
for(;;){
//永远不会停止
}
在while循环中:
TypeScript
while (true) {
// 同样永无止境
}
"无限循环" 从表面上看像"永不停歇的机器人",可是如果没有适当的"退出机制 (break / return /条件判断...)",就容易让程序卡死、资源耗光。使用时务必小心。
总结
锤子、螺丝刀、电钻......
不同的循环方式,就像不同的工具,选对工具,你的代码更可靠、更简洁、更高效。
| 循环方式 | 核心用途 | 是否关心索引 | 典型场景 |
|---|---|---|---|
| for | 精确控制次数 | 是 | 已知循环次数 |
| for...in | 遍历键 / 索引 | 是 | 对象属性、索引 |
| for...of | 遍历值 | 否 | 数组、字符串、Set |
| forEach | 回调式遍历 | 否 | 简单遍历(不中断) |
| while | 条件驱动循环 | 否 | 次数未知 |
| do...while | 至少执行一次 | 否 | 必须先执行 |
| break | 控制循环流程 | 否 | 提前退出 |
| continue | 控制循环流程 | 否 | 跳过当次 |