,# JS循环大乱斗,10种方式玩转数据遍历,JavaScript 中的数据遍历看似简单,但背后隐藏着丰富的语法和灵活的使用方式,本文将带你进入一场“循环大乱斗”,探索 JavaScript 提供的 10 种独特且强大的数据遍历方法,从经典的for
循环和数组自带的forEach
、map
、filter
、reduce
,到更现代的for...of
、yield*
、async/await
(用于异步数据流),甚至Promise.all
和Object.keys
等变体,每一种方法都有其独特的语法和适用场景,文章将通过实例对比它们的语法差异、执行逻辑、性能特点以及适用范围,帮助你理解何时选择哪种循环方式,从而让你的代码不仅功能正确,更能写出更简洁、更高效、更符合现代 JavaScript 风格的遍历逻辑,无论你是 JavaScript 新手还是资深开发者,都能从中发现新的技巧和思路,让你的数据处理能力更上一层楼。
大家好,我是程序员小张,今天咱们不聊高深的算法,就来唠唠JavaScript中最实用的循环技巧,别看循环是个基础功能,用好了能让你的代码优雅得像首诗,用不好可能让浏览器CPU直接干冒烟,来,跟着我一起进入循环的奇幻世界!
循环是什么?为啥要学?
想象你是个餐厅服务员,需要给每位客人上菜,客人来了(初始化),你按顺序上菜(循环体),直到所有客人都吃完了(终止条件),这就是循环的精髓——重复执行一段代码直到满足特定条件。
在JS中,循环就像你的魔法棒,能帮你:
- 批量处理数据(比如给100个用户发消息)
- 自动化重复任务(比如每秒检查一次库存)
- 实现复杂逻辑(比如实现一个简易计算器)
循环家族成员大乱斗
基础款:for循环
:初始化、条件判断、迭代器
for(let i = 0; i < 10; i++) { console.log(i); // 输出0到9 }
适用场景:当你确切知道要循环多少次时
优点:结构清晰,控制灵活 缺点:需要手动管理循环变量
案例:计算10的阶乘
let result = 1; for(let i = 1; i <= 10; i++) { result *= i; } console.log(result); // 3628800
条件判断型:while循环
:只要条件满足就继续
let i = 0; while(i < 5) { console.log(i); i++; }
适用场景:当你不确定循环次数,但知道终止条件时
注意:忘记更新循环变量会导致无限循环!
案例:模拟用户登录尝试
let attempts = 0; while(attempts < 3) { const username = prompt("请输入用户名"); if(username === "admin") { alert("登录成功!"); break; } attempts++; }
保险型:do-while循环
:至少执行一次
let i = 0; do { console.log(i); i++; } while(i < 5);
适用场景:需要先执行一次再判断的情况
案例:用户必须至少输入一次密码
let correct = false; do { const password = prompt("请输入密码"); if(password === "secret") { correct = true; } } while(!correct);
对象遍历者:for...in循环
:遍历对象的可枚举属性
const person = {name: "张三", age: 20, job: "程序员"}; for(let key in person) { console.log(`${key}: ${person[key]}`); }
适用场景:遍历对象属性
注意事项:可能会遍历原型链上的属性!
案例:获取对象所有值
function getAllValues(obj) { const values = []; for(let key in obj) { if(obj.hasOwnProperty(key)) { values.push(obj[key]); } } return values; }
迭代新贵:for...of循环
:遍历可迭代对象的值
const arr = [1,2,3]; for(let value of arr) { console.log(value); }
适用场景:遍历数组、字符串、类数组对象
优点:不需要索引,代码更简洁
案例:统计字符串字符数
let count = 0; const str = "hello"; for(let char of str) { count++; } console.log(count); // 5
优雅的forEach
:数组专属,无返回值
[1,2,3].forEach(item => { console.log(item); });
适用场景:对数组进行只读操作
注意:不能在循环中break/return修改数组!
案例:给数组元素加前缀
const names = ["张三", "李四", "王五"]; names.forEach((name, index) => { names[index] = "Dr." + name; });
高级玩家:map循环
:创建新数组
const squares = [1,2,3].map(num => num * num);
适用场景:转换数组元素
案例:将字符串数组转为大写
const cities = ["beijing", "shanghai", "guangzhou"]; const upperCities = cities.map(city => city.toUpperCase());
筛选专家:filter循环
:创建新数组,保留满足条件的元素
const evenNumbers = [1,2,3,4,5].filter(num => num % 2 === 0);
案例:获取所有成年人
const users = [{name: "张三", age: 18}, {name: "李四", age: 25}]; const adults = users.filter(user => user.age >= 18);
终极奥义:reduce循环
:将数组缩减为单一值
const sum = [1,2,3,4].reduce((acc, curr) => acc + curr, 0);
适用场景:计算总和、最大值、拼接字符串等
案例:合并数组
const words = ["hello", "world"]; const sentence = words.reduce((acc, word) => acc + " " + word, "");
循环选择指南
循环类型 | 主要用途 | 是否修改原数组 | 是否需要索引 | 是否支持对象 |
---|---|---|---|---|
for | 已知循环次数 | |||
while/do-while | 条件判断 | |||
for...in | 遍历对象属性 | |||
for...of | 遍历可迭代对象 | |||
forEach | 数组遍历 | |||
map | 创建新数组 | |||
filter | 筛选元素 | |||
reduce | 计算单一值 |
常见问题解答
问:for和while有什么区别? 答:for更适合已知循环次数的情况,语法包含初始化、条件判断和迭代三部分;while更适合条件判断,需要手动控制循环变量。
问:什么时候用for...in不安全? 答:当对象继承了原型链上的属性时,for...in会遍历这些属性,使用hasOwnProperty可以过滤。
问:如何跳出循环? 答:可以用break跳出当前循环,用return跳出函数中的循环,用throw抛出自定义错误。
问:循环中修改数组会怎样? 答:使用for循环时,修改数组会导致索引错乱;使用forEach时,修改原数组可能导致跳过某些元素;使用map时,修改原数组不会影响结果。
实战案例:购物车结算系统
// 购物车数据 const cart = [ {name: "iPhone", price: 5999, quantity: 1}, {name: "MacBook", price: 12999, quantity: 1}, {name: "AirPods", price: 1199, quantity: 2} ]; // 计算总价 const total = cart.reduce((sum, item) => sum + item.price * item.quantity, 0); // 应用折扣(会员8折) const discountRate = 0.8; const discountedTotal = total * discountRate; // 生成订单信息 const orderInfo = cart.map(item => `${item.name} x${item.quantity} - ${item.price * item.quantity}元` ).join("\n"); // 显示订单信息 console.log(`订单明细:\n${orderInfo}\n\n`); console.log(`原价:${total.toFixed(2)}元\n`); console.log(`会员折扣价:${discountedTotal.toFixed(2)}元`);
循环是JS开发的基础技能,但真正掌握它需要理解每种循环的适用场景和潜在陷阱。
- 根据需求选择合适的循环类型
- 注意循环条件,避免无限循环
- 在修改数组时要小心
- 利用ES6+的新特性简化代码
- 合理使用break/continue/return控制流程
最后送大家一句编程名言:"循环用得好,bug没来找;循环用不好,CPU直冒泡",希望这篇大乱斗能帮你轻松掌握JS循环,写出更优雅的代码!
知识扩展阅读
大家好!今天我们来聊聊JavaScript中的循环,无论是前端还是后端开发,循环都是编程中不可或缺的一部分,在JavaScript中,我们有几种常见的循环类型,每种循环都有其特定的用途和场景,我们就一起来了解一下这些循环以及它们的使用场景。 JavaScript中的循环类型概览
在JavaScript中,常见的循环类型包括:
- for循环
- while循环
- do-while循环
- for...in循环
- for...of循环
- 数组和集合的迭代方法(如map、filter等)
我们将逐一介绍这些循环类型。
for循环
for循环是最基础的循环类型之一,它允许我们设定一个固定的迭代次数,并在每次迭代中执行一段代码。
for (let i = 0; i < 5; i++) { console.log(i); // 输出0到4 }
while循环
while循环会在条件满足时一直执行代码块,直到条件不再满足为止。
let i = 0; while (i < 5) { console.log(i); // 输出0到4 i++; }
do-while循环
do-while循环与while循环相似,但区别在于它至少会执行一次代码块,然后再检查条件。
let i = 0; do { console.log(i); // 输出0到至少一次,取决于条件是否满足递减或不变的情况,如果条件始终为真,则无限次输出,否则在条件不满足时停止输出,如果初始条件为假,则不会输出任何内容,使用do-while循环时需要谨慎设置初始条件和退出条件,否则可能导致无限循环,消耗大量资源甚至导致程序崩溃,为了避免这种情况,建议在编写do-while循环时设置一个明确的退出条件,以确保循环能够正常结束,还需要注意避免在循环体内修改影响退出条件的变量值,否则可能导致无法预期的结果,do-while循环通常用于需要至少执行一次代码块的情况,即使初始条件不满足也是如此,在某些情况下,do-while循环可能是比while循环更好的选择。五、for...in循环for...in循环主要用于遍历对象的属性,let obj = {a: 1, b: 2, c: 3};for (let key in obj) { console.log(key); // 输出属性名 } 六、for...of循环for...of循环用于遍历可迭代对象(如数组、字符串等)的元素,let arr = [1, 2, 3];for (let value of arr) { console.log(value); // 输出数组元素 } 七、数组和集合的迭代方法除了上述传统的循环结构外,JavaScript的数组和集合还提供了许多迭代方法(如map、filter等),这些方法可以在遍历元素的同时进行更复杂的操作,let arr = [1, 2, 3];arr.map(function(value) { console.log(value * 2); // 输出每个元素的两倍值 });这些方法通常用于对数组或集合进行转换或过滤等操作,可以简化代码并提高效率。八、案例说明假设我们有一个任务需要打印从1到10的所有数字,我们可以使用不同的循环类型来实现这个任务。使用for循环: for (let i = 1; i <= 10; i++) { console.log(i); } 使用while循环: let i = 1; while (i <= 10) { console.log(i); i++; } 使用do-while循环(虽然不太常见): let i = 1; do { console.log(i); i++; } while (i <= 10); *以上就是JavaScript中常见的几种循环类型及其用法,在实际开发中,我们可以根据具体需求和场景选择合适的循环类型来提高开发效率和代码质量,同时还需要注意避免一些常见的错误和陷阱如无限循环等问题,希望这篇文章能帮助大家更好地理解和掌握JavaScript中的循环类型和使用方法,在实际开发中遇到问题时可以根据具体情况选择合适的循环类型来解决遇到的问题,同时还需要不断学习和探索新的技术和方法以提高自己的编程能力和水平。
相关的知识点: