JavaScript循环是重复执行代码的核心控制结构,主要分为基础循环(for、while、do-while)和遍历循环(for...of、for...in、forEach、map等),for循环适合明确次数的迭代,while/do-while基于条件判断;for...of遍历数组、字符串等可迭代对象的值,for...in用于对象属性遍历(需注意原型链);数组的forEach执行回调但不返回新值,map则返回处理后的新数组,循环在数据处理、DOM操作等场景中不可或缺,合理选择可提升代码效率与可读性。
JavaScript循环全解析:从基础语法到实战技巧
在JavaScript编程中,循环是处理重复任务的核心工具,无论是遍历数组、处理对象数据,还是执行需要重复计算的逻辑,循环都扮演着不可或缺的角色,本文将从基础语法出发,系统讲解JavaScript中常见的循环类型,分析它们的适用场景与注意事项,并结合实例助你掌握循环的使用技巧。
初识循环:为什么需要循环?
想象一个场景:你需要计算1到100所有整数的和,或者遍历一个包含100个元素的数组并输出每个元素,如果不用循环,你可能需要写100行重复的代码——这不仅效率低下,而且难以维护,循环的出现,就是为了解决这种"重复执行"的需求:通过设定初始条件、循环条件和更新逻辑,让代码自动重复执行,直到满足某个终止条件。
在实际开发中,循环的应用场景非常广泛:
- 处理用户输入验证
- 批量处理数据
- 实现动画效果
- 网络请求的重试机制
- 数据库查询结果的遍历
基础循环:for循环
for循环是JavaScript中最常用的循环类型,它通过三个关键表达式(初始化、条件判断、更新)控制循环流程,结构清晰,适合明确循环次数的场景。
语法结构
for (初始化表达式; 条件表达式; 更新表达式) {
// 循环体(需要重复执行的代码)
}
执行流程
- 初始化表达式:循环开始前执行,通常用于初始化循环变量(如
let i = 0),且仅执行一次。 - 条件表达式:每次循环前判断,若结果为
true,则执行循环体;若为false,则终止循环。 - 更新表达式:每次循环体执行完毕后执行,通常用于更新循环变量(如
i++)。
实例:遍历数组并求和
const numbers = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i]; // 累加数组元素
}
console.log(sum); // 输出:15
高级用法与注意事项
- 嵌套循环:处理多维数据结构
const matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];
for (let i = 0; i < matrix.length; i++) { for (let j = 0; j < matrix[i].length; j++) { console.log(matrix[i][j]); } }
2. **循环控制语句**:
- `break`:立即跳出当前循环
- `continue`:跳过本次循环,继续下一次循环
3. **性能优化**:避免在循环条件中执行复杂计算
```javascript
// 不推荐
for (let i = 0; i < expensiveFunction(); i++) {
// ...
}
// 推荐
const length = expensiveFunction();
for (let i = 0; i < length; i++) {
// ...
}
适用场景
- 已知循环次数的场景(如遍历数组、固定次数计算)
- 需要精确控制循环变量变化的场景(如步长不为1的循环:
for (let i = 0; i < 10; i += 2)) - 需要访问索引的场景
条件循环:while与do-while
当循环次数不确定,需要依赖某个条件判断是否继续循环时,while和do-while循环更为适用。
while循环:先判断,后执行
while循环会在每次循环前先判断条件,只有条件为true时才会执行循环体。
语法结构
while (条件表达式) {
// 循环体
}
实例:猜数字游戏
const targetNumber = Math.floor(Math.random() * 10) + 1; // 1-10随机数
let guess = 0;
let attempts = 0;
while (guess !== targetNumber && attempts < 5) {
guess = parseInt(prompt("请猜一个1-10的数字:"));
attempts++;
if (guess < targetNumber) {
alert("猜小了!");
} else if (guess > targetNumber) {
alert("猜大了!");
}
}
if (guess === targetNumber) {
alert(`恭喜你,猜对了!用了${attempts}次`);
} else {
alert(`游戏结束!正确答案是${targetNumber}`);
}
do-while循环:先执行,后判断
do-while循环与while的区别在于:它会先执行一次循环体,再判断条件,这意味着即使初始条件为false,循环体至少会执行一次。
语法结构
do {
// 循环体
} while (条件表达式);
实例:确保用户输入有效
let input;
do {
input = prompt("请输入"yes"继续:");
if (input === null) {
alert("操作已取消");
break;
}
} while (input !== "yes" && input !== null);
if (input === "yes") {
console.log("输入有效,程序继续执行");
}
while与do-while的区别
| 特性 | while循环 | do-while循环 |
|---|---|---|
| 执行顺序 | 先判断条件,后执行 | 先执行,后判断条件 |
| 最少执行次数 | 0次(条件为false时不执行) | 1次(无条件执行一次) |
| 适用场景 | 条件可能不满足的场景 | 至少需要执行一次的场景 |
遍历专用循环:for-in与for-of
在ES6之前,遍历对象或数组主要依靠for循环,但ES6新增了for-in和for-of循环,让遍历更简洁。
for-in循环:遍历对象的可枚举属性
for-in循环主要用于遍历对象的可枚举属性(包括原型链上的属性),返回的是属性名(键)。
语法结构
for (const key in object) {
// 循环体,key为属性名
}
实例:遍历对象属性
const person = {
name: "张三",
age: 18,
gender: "男"
};
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
// 输出:
// name: 张三
// age: 18
// gender: 男
注意事项
- 遍历数组时,
for-in会返回数组索引(但本质是字符串类型),且可能遍历到原型链上的属性,不推荐用于数组遍历。 - 若需过滤原型链属性,可用
hasOwnProperty方法:
for (const key in person) {
if (Object.prototype.hasOwnProperty.call(person, key)) {
console.log(`${key}: ${person[key]}`);
}
}
遍历顺序:属性的枚举顺序可能因JavaScript引擎而异,不保证特定顺序。
for-of循环:遍历可迭代对象的值
for-of是ES6新增的循环方式,用于遍历可迭代对象(如数组、字符串、Map、Set等),直接返回元素的值,语法更简洁,且不会遍历原型链上的属性。
语法结构
for (const value of iterable) {
// 循环体,value为元素值
}
实例:遍历数组与字符串
// 遍历数组 const fruits = ["苹果", "香蕉", "橙