news 2026/6/23 18:28:51

JavaScript中的循环特点和区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript中的循环特点和区别

一、前言:循环在 JS 中的核心地位

循环是编程的基础逻辑之一,在 JavaScript 中更是贯穿前端开发、Node.js 后端等所有场景 —— 从 DOM 遍历、数据处理到异步流程控制,几乎无处不在。但多数开发者仅停留在for/forEach的基础使用,忽略了不同循环的适用场景、性能差异和进阶技巧。本文将从基础语法到实战优化,全面拆解 JS 循环的核心知识点,帮你掌握 “什么时候用什么循环” 的底层逻辑。

二、JS 循环的 5 大核心类型:语法与基础用法

1. 传统循环:for/while/do...while

这是最基础的循环类型,兼容性覆盖所有浏览器(包括 IE),核心优势是完全可控(可中断、可跳过、可反向遍历)。

  • for循环:适合已知遍历次数的场景

// 正向遍历数组

const arr = [1, 2, 3, 4];

for (let i = 0; i < arr.length; i++) {

console.log(arr[i]); // 1,2,3,4

}

// 反向遍历(性能更优,减少数组长度读取)

for (let i = arr.length - 1; i >= 0; i--) {

console.log(arr[i]); // 4,3,2,1

}

  • while循环:适合未知遍历次数的场景(需手动控制终止条件)

let count = 0;

while (count ) {

console.log(count); // 0,1,2

count++;

}

  • do...while循环:与while的区别是至少执行一次

let count = 3;

do {

console.log(count); // 3(即使条件不满足,仍执行一次)

count++;

} while (count );

2. 数组专用循环:forEach

ES5 引入的数组遍历方法,语法简洁,无需手动控制索引,但无法中断循环(break/return无效,return仅相当于跳过当前迭代)。

const arr = [1, 2, 3];

arr.forEach((item, index, array) => {

if (item === 2) return; // 跳过当前项,继续执行下一次

console.log(item); // 1,3

});

⚠️ 注意:forEach遍历稀疏数组时,会跳过空元素(与for循环不同)。

3. 迭代器循环:for...in/for...of

ES6 引入的新型循环,基于迭代器(Iterator)协议,适用于不同数据结构的遍历。

  • for...in:遍历对象的可枚举属性(包括原型链上的属性),不建议用于数组(会遍历数组的索引及自定义属性)。

const obj = { name: "张三", age: 20 };

for (const key in obj) {

// 过滤原型链属性

if (obj.hasOwnProperty(key)) {

console.log(`${key}: ${obj[key]}`); // name: 张三, age: 20

}

}

  • for...of:遍历可迭代对象(数组、字符串、Map、Set 等)的,支持break/continue/return中断循环,是数组遍历的优选方案。

// 遍历数组

const arr = [1, 2, 3];

for (const item of arr) {

if (item === 2) break; // 中断循环

console.log(item); // 1

}

// 遍历Map

const map = new Map([["name", "张三"], ["age", 20]]);

for (const [key, value] of map) {

console.log(`${key}: ${value}`); // name: 张三, age: 20

}

三、关键对比:不同循环的适用场景与性能

1. 功能对比表

循环类型

适用场景

能否中断

遍历空元素

遍历原型属性

for

数组、已知次数的遍历

-

while/do...while

未知次数的遍历

-

-

forEach

数组遍历(无需中断)

-

for...in

对象属性遍历

-

是(需过滤)

for...of

可迭代对象的值遍历

否(数组)

-

2. 性能分析(基于 Chrome 浏览器测试)
  • 性能排序(从快到慢):for(反向)> for(正向)> for...of > forEach > for...in
  • 核心原因:
    • for循环无额外函数调用和迭代器开销,直接操作索引,性能最优;
    • for...of基于迭代器,但底层优化较好,性能接近for;
    • forEach每次迭代需调用回调函数,存在函数调用开销;
    • for...in需遍历原型链属性,且需判断属性是否为自身所有,性能最差。

⚠️ 注意:性能差异仅在大数据量(10 万 + 条数据)下明显,日常开发中优先考虑代码可读性,无需过度优化。

四、进阶技巧:循环的高级用法与避坑指南

1. 中断循环的正确方式
  • 可中断循环:for/while/do...while/for...of(用break中断,continue跳过当前迭代);
  • 不可中断循环:forEach(需中断时,建议替换为for...of或for循环);
  • 替代方案:数组方法some/every(本质是遍历,但可通过return true中断):

const arr = [1, 2, 3];

// some:找到满足条件的项后中断,返回true

arr.some(item => {

if (item === 2) return true;

console.log(item); // 1

});

2. 异步循环的坑与解决方案

问题:forEach/for...in中使用异步操作(如setTimeout、接口请求)时,循环会先执行完,异步回调才触发,导致索引 / 值错乱。

// 错误示例:所有回调都打印4(i最终为4)

const arr = [1, 2, 3];

for (var i = 0; i < arr.length; i++) {

setTimeout(() => console.log(arr[i]), 0);

}

解决方案

  • 用let声明索引(块级作用域,每次迭代创建独立变量);
  • 用for...of(天然支持异步中断);
  • 用Promise.all(并行执行异步操作)。

// 正确示例:用for...of

const arr = [1, 2, 3];

async function asyncLoop() {

for (const item of arr) {

await new Promise(resolve => setTimeout(() => {

console.log(item); // 1,2,3(顺序执行)

resolve();

}, 1000));

}

}

asyncLoop();

3. 循环优化技巧
  • 数组遍历前缓存长度:`for (let i = 0, len = arr.length; i (避免每次迭代读取数组长度);
  • 反向遍历数组:减少数组索引边界判断(i >= 0比 `i 简单);
  • 大数据量遍历用for或for...of,避免forEach和for...in;
  • 遍历对象属性时,用Object.keys(obj).forEach替代for...in(避免原型链问题)。

五、实战场景:循环的最佳实践

  1. 场景 1:数组遍历并中断→ 用for...of或for循环;
  1. 场景 2:数组遍历无需中断,追求简洁→ 用forEach;
  1. 场景 3:对象属性遍历→ 用Object.keys(obj).forEach或for...in(需过滤原型链);
  1. 场景 4:Map/Set 遍历→ 用for...of;
  1. 场景 5:异步遍历(顺序执行)→ 用for...of+async/await;
  1. 场景 6:异步遍历(并行执行)→ 用Promise.all(arr.map(async item => {}))。

六、总结

JavaScript 循环的核心是 “选择合适的工具解决对应问题”:基础场景用for/forEach,对象遍历用Object.keys+forEach,可迭代对象用for...of,异步场景用for...of+async/await。掌握不同循环的语法、性能和适用场景,不仅能提升代码可读性,还能在大数据量场景下优化性能。

记住:没有最好的循环,只有最适合的循环。在实际开发中,需结合业务场景、代码可读性和性能需求综合选择。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/21 8:04:58

伊朗地毯数据集,波斯地毯Lechak-Toranj和Afshan图案分类,计算机视觉机器学习训练,纺织设计分析增强样本,装饰艺术特征提取对称检测算法,纹理分析Gabor滤波,个性化定制图案生成

伊朗地毯数据集&#xff0c;波斯地毯Lechak-Toranj和Afshan图案分类&#xff0c;计算机视觉机器学习训练&#xff0c;纺织设计分析增强样本&#xff0c;装饰艺术特征提取对称检测算法&#xff0c;纹理分析Gabor滤波&#xff0c;个性化定制图案生成 在传统艺术文化遗产保护、纺…

作者头像 李华
网站建设 2026/6/22 20:32:05

[基础算法学习]backtrack回溯法(三):从N皇后、解数独带你掌握棋盘回溯问题

[基础算法学习]backtrack回溯法(三):从N皇后、解数独带你掌握棋盘回溯问题 在回溯法(一)和回溯法(二)两篇文章中&#xff0c;介绍了回溯法的万能模版以及树枝去重、树层去重剪枝技巧。本文将继续讲解回溯法中较难一类问题——棋盘问题&#xff0c;并通过N皇后和 解数独两道经典…

作者头像 李华
网站建设 2026/6/23 5:28:37

Go之路 - 7.go的函数

一、函数基础 1.1 函数声明 // 基本语法 func 函数名(参数列表) (返回值列表) {// 函数体 }// 示例 func add(x int, y int) int {return x y }// 简化参数类型&#xff08;相同类型&#xff09; func multiply(x, y int) int {return x * y }1.2 多返回值 // 返回多个值 func…

作者头像 李华
网站建设 2026/6/22 15:25:59

Chet.QuartzNet.UI 基于VbenAdmin框架的现代化UI体验

&#x1f525; Chet.QuartzNet.UI 基于VbenAdmin框架的现代化UI体验 &#x1f3af; 为什么VbenAdmin是个好选择&#xff1f; Chet.QuartzNet.UI 采用了 VbenAdmin 作为前端框架&#xff0c;VbenAdmin 是一款基于 Vue 3 TypeScript Ant Design Vue 开发的现代化管理系统框架&a…

作者头像 李华
网站建设 2026/6/23 3:01:20

AI 在泛前端领域的思考和实践-上篇

在大模型、AI Agent、Vibe Coding 与 Spec Coding 飞速发展的浪潮中&#xff0c;AI 与泛前端的融合正引发行业的深度思考&#xff1a;AI 究竟会 “替代” 传统开发模式&#xff0c;还是会推动一场效率与体验的全新 “革命”&#xff1f;它又将为泛前端领域带来哪些底层变革&…

作者头像 李华