JavaScript循环全攻略,告别重复代码的泥潭
想象一下,让你在控制台打印100遍“我要学好编程”。如果没有循环,你就要写100行 console.log,这显然不现实。循环的出现,就是为了解决这类“重复性劳动”。
JavaScript循环是一种让代码块可以重复执行的机制。它就像一个不知疲倦的工人,只要你下达指令(设置好条件),它就会一直干下去,直到你喊停(条件不再满足)。
很多刚开始学习编程的朋友,对“什么时候该用哪个循环”感到困惑。这很正常,因为JavaScript贴心地提供了好几种循环工具,每种都有自己的脾气和擅长领域。今天我们就来彻底理清它们。
JavaScript循环大家族巡礼
JavaScript中的循环主要分为以下几种:
-
for循环:最经典、最常用的循环,适合“我知道要循环多少次”的场景。 -
while循环:适合“我不知道要循环多少次,但我知道什么时候该停下来”的场景。 -
do...while循环:while循环的“表亲”,特点是不管条件是否满足,先干一次再说。 -
for...in循环:专门用来遍历对象的“钥匙”(属性名)。 -
for...of循环:专门用来遍历数组、字符串等可迭代对象的“值”(ES6引入的新特性)。
下面我们逐个击破。
1. 精准控制的 for 循环
for 循环是三兄弟里最工整、最结构化的一个。它把“从哪里开始”、“到哪里结束”、“每一步怎么走”这三件事写在了一行。
语法结构:
for (初始化; 条件; 增量/减量) {
// 要重复执行的代码块
}
学习编程示例: 计算1到100的总和。
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += i; // 等价于 sum = sum + i
}
console.log(`1加到100的结果是:${sum}`);
// 输出:1加到100的结果是:5050
执行流程解析:
-
let i = 1初始化,只执行一次。 -
判断
i <= 100是否为真。为真,则执行循环体sum += i。 -
执行
i++,i变成2。 -
回到第2步,再次判断
i <= 100。 -
直到
i变成101,条件为假,循环结束。
个人见解: for 循环是我个人最常用的循环。当我们需要遍历数组时,虽然 for...of 更简洁,但 for 循环的优势是灵活。我可以随意控制索引 i 的步长,比如 i+=2 来遍历偶数位,或者在满足某个内部条件时提前用 break 跳出循环。这种掌控感是他循环难以替代的。
2. 灵活机动的 while 循环
while 循环像一个有耐心的门卫,只要条件为真,就一直放行。它不知道要放行多少人,只知道“直到没人了为止”。
语法结构:
while (条件) {
// 要重复执行的代码块
// 在这里改变条件中涉及的变量,避免死循环
}
学习编程示例: 一个简单的猜数字游戏逻辑。
let targetNumber = 7;
let guess = 0;
let attempts = 0;
while (guess !== targetNumber) {
// 这里模拟用户输入,实际开发中是读取输入框的值
guess = Math.floor(Math.random() * 10) + 1; // 随机生成1-10的数字
attempts++;
console.log(`第${attempts}次猜测:${guess}`);
}
console.log(`恭喜!你在第${attempts}次猜中了数字${targetNumber}!`);
为什么用 while? 这个例子中,我们无法预判需要循环多少次才能猜中,一次就中,也十次。条件 guess !== targetNumber 是否成立,取决于循环内部动态生成的 guess。这正是 while 循环的用武之地。
3. 先斩后奏的 do...while 循环
do...while 和 while 的区别仅在于:do...while 至少会执行一次循环体,然后再判断条件。这就好比“先上车,后补票”。
语法结构:
do {
// 至少执行一次的代码块
} while (条件);
学习编程示例: 用户输入验证。
let userInput;
do {
// 提示用户输入一个大于0的数字
userInput = prompt("请输入一个正整数:");
// 简单校验,如果用户取消或输入非数字,prompt会返回null或空字符串
if (userInput === null) {
console.log("您取消了输入。");
break; // 跳出循环
}
userInput = parseInt(userInput, 10);
} while (isNaN(userInput) || userInput <= 0);
if (userInput > 0) {
console.log(`您输入了有效的数字:${userInput}`);
}
个人建议: 这个场景用 do...while 非常合适。因为无论如何,我们至少要提示用户输入一次。如果用 while,我们不得不在循环前也写一遍提示代码,造成重复。在实际开发中,比如显示菜单、处理用户首次操作等场景,do...while 能让代码更简洁。
4. 专攻对象的 for...in 循环
for...in 是专门为遍历对象属性(键名)而设计的。
语法结构:
for (let 键名 in 对象) {
// 可以通过 对象[键名] 访问对应的值
}
学习编程示例: 打印个人资料卡。
const person = {
name: '代码号小编',
age: 18,
city: '北京',
hobby: '编程'
};
console.log('--- 个人资料 ---');
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
console.log('--- 资料卡结束 ---');
// 输出:
// --- 个人资料 ---
// name: 代码号小编
// age: 18
// city: 北京
// hobby: 编程
// --- 资料卡结束 ---
特别注意: for...in 遍历的顺序是不确定的,特别是在不同的JavaScript引擎中。不要依赖 for...in 的遍历顺序。它也会遍历到对象原型链上可枚举的属性,需要用 hasOwnProperty 方法过滤一下,确保只处理对象自身的属性。
5. 简洁现代的 for...of 循环
for...of 是ES6引入的新特性,它提供了一种统一、简洁的方式来遍历所有“可迭代对象”,比如数组、字符串、Map、Set等。它直接获取值,而不是索引或键名。
语法结构:
for (let 值 of 可迭代对象) {
// 直接操作值
}
编程示例: 遍历购物车商品列表。
const shoppingCart = ['《JavaScript高级程序设计》', '机械键盘', '降噪耳机', '代码号T恤'];
console.log('您的购物车中有:');
for (let item of shoppingCart) {
console.log(` - ${item}`);
}
// 输出:
// 您的购物车中有:
// - 《JavaScript高级程序设计》
// - 机械键盘
// - 降噪耳机
// - 代码号T恤
为什么极力推荐 for...of?
想当年,我们遍历数组只能用 for 循环或者 forEach 方法。for 循环要写索引,略显繁琐;forEach 虽然简洁,但不能用 break、continue 或 return 语句来控制流程。
for...of 结合了二者的优点:
-
简洁:直接拿到值,不需要关心索引。
-
灵活:可以使用
break、continue来控制循环。 -
通用:适用于所有可迭代对象(数组、字符串、Set、Map等)。
比如,想打印购物车里的商品,但只打印到“机械键盘”为止:
for (let item of shoppingCart) {
if (item === '机械键盘') {
console.log(`发现${item},检查完毕,停止打印。`);
break;
}
console.log(` - ${item}`);
}
// 输出:
// - 《JavaScript高级程序设计》
// 发现机械键盘,检查完毕,停止打印。
这是 forEach 无法做到的。
如何选择正确的循环?一节课程知识要点
面对这么多选择,如何下手?记住下面这张速查表:
| 场景 | 推荐使用的循环 | 核心原因 |
|---|---|---|
| 明确知道要循环多少次 | for 循环 |
结构清晰,初始化、条件、迭代写在一起,方便控制。 |
| 只知道循环何时停止,次数未知 | while 循环 |
灵活性高,专注于循环条件。 |
| 循环体至少需要执行一次 | do...while 循环 |
保证代码块至少运行一次,避免代码重复。 |
| 需要遍历对象的属性(键名) | for...in 循环 |
为遍历对象属性设计,能拿到属性名。 |
| 需要遍历数组、字符串等可迭代对象的值 | for...of 循环 |
语法最简洁,现代JavaScript优选,支持 break/continue。 |
循环是编程的基石之一。理解并熟练运用这五种循环,能让你在处理重复任务、遍历数据时游刃有余。