js遍历数组和对象的常用方法有哪些?

精通 JS 遍历:数组与对象的高效遍历方法论(2026 版)

遍历是 JavaScript 数据处理的基石,从前端 DOM 渲染到后端数据聚合,几乎所有业务场景都离不开数组和对象的遍历操作。但新手常陷入 “方法用错、性能低效、边界踩坑” 的困境 —— 比如用for...in遍历数组、用forEach强行终止循环、忽略reduce初始值导致异常。本文将从场景适配性能优化避坑指南三个维度,系统拆解数组与对象的遍历方法,结合实战案例和最佳实践,帮你实现 “选对方法、写对代码、用对性能” 的目标。

一、数组遍历:按场景选方法,而非 “一招鲜”

数组遍历的核心是 “匹配业务意图”:是单纯遍历?是生成新数组?是筛选数据?还是聚合计算?不同意图对应不同最优方法,以下按 “基础可控型”“函数式迭代型”“特殊场景型” 分类讲解。

1. 基础可控型遍历(性能优先)

这类方法完全掌控遍历过程,支持终止 / 跳过,适合大数据量、需精细控制的场景。

(1)原生 for 循环(性能天花板)

最底层、性能最优的遍历方式,无任何额外开销,适合 10 万级以上大数据量遍历。

javascript

运行

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // 基础版 for (let i = 0; i < arr.length; i++) { // 终止循环:找到第一个大于5的数就停止 if (arr[i] > 5) { console.log("找到目标值:", arr[i]); break; } console.log("当前值:", arr[i]); } // 性能优化版(缓存长度,避免每次读取arr.length) for (let i = 0, len = arr.length; i < len; i++) { // 跳过偶数 if (arr[i] % 2 === 0) continue; console.log("奇数:", arr[i]); } // 反向遍历(适合从后删除元素的场景) for (let i = arr.length - 1; i >= 0; i--) { if (arr[i] < 3) arr.splice(i, 1); // 从后删除避免索引错乱 } console.log(arr); // [3,4,5,6,7,8,9,10]

核心优势

  • 性能第一,无函数调用、迭代器等额外开销;
  • 支持break(终止)、continue(跳过)、反向遍历;
  • 可直接操作索引,适合修改原数组的场景。
(2)for...of 循环(ES6+,简洁可控)

ES6 迭代器语法,兼顾简洁性和可控性,支持遍历所有可迭代对象(数组、Set、Map、字符串等)。

javascript

运行

const arr = [1, 2, 3, 4, 5]; // 基础遍历元素 for (const item of arr) { if (item === 3) break; // 支持终止 console.log(item); // 1,2 } // 同时获取索引和元素(结合entries()) for (const [index, item] of arr.entries()) { console.log(`索引${index}:${item}`); } // 遍历Set(可迭代对象示例) const set = new Set([1, 2, 3]); for (const item of set) { console.log(item); }

核心优势

  • 语法简洁,比原生 for 循环易读;
  • 支持break/continue,弥补 forEach 的缺陷;
  • 适配所有可迭代对象,通用性强。

2. 函数式迭代方法(可读性优先)

ES5+ 新增的数组原型方法,基于函数式编程思想,无需手动控制索引,是日常开发的主流选择。所有方法均不修改原数组,核心差异在于 “返回值” 和 “终止逻辑”。

核心方法对比表(建议收藏)
方法名核心用途返回值终止逻辑典型场景
forEach单纯遍历无(undefined)无法终止(return 仅跳过当前轮次)列表渲染、无返回值的遍历操作
map映射转换新数组(长度与原数组一致)无终止(遍历所有元素)数据格式转换(如接口数据适配)
filter筛选数据新数组(符合条件的元素)无终止(遍历所有元素)条件筛选(如筛选已完成的任务)
some存在性判断布尔值(true/false)返回 true 时立即终止判断是否有符合条件的元素
every全量判断布尔值(true/false)返回 false 时立即终止判断所有元素是否符合规则
find查找元素第一个符合条件的元素 /undefined返回 true 时立即终止查找唯一元素(如根据 ID 找用户)
findIndex查找索引第一个符合条件的索引 /-1返回 true 时立即终止查找元素位置(如定位错误数据)
reduce聚合计算最终聚合值无终止(遍历所有元素)求和、拼接、扁平化数组等
实战示例(带业务场景)

javascript

运行

const users = [ { id: 1, name: "张三", age: 22, status: "active" }, { id: 2, name: "李四", age: 18, status: "inactive" }, { id: 3, name: "王五", age: 25, status: "active" }, ]; // 1. forEach:渲染用户列表(无返回值) users.forEach(user => { console.log(`用户${user.name}:状态${user.status}`); }); // 2. map:转换数据格式(前端适配) const userOptions = users.map(user => ({ label: user.name, value: user.id })); console.log(userOptions); // [{label: '张三', value: 1}, {label: '李四', value: 2}, {label: '王五', value: 3}] // 3. filter:筛选活跃用户 const activeUsers = users.filter(user => user.status === "active"); console.log(activeUsers); // 张三、王五 // 4. some:判断是否有未成年用户 const hasMinor = users.some(user => user.age < 18); console.log(hasMinor); // false(李四18岁,不满足<18) // 5. every:判断所有用户是否成年 const allAdult = users.every(user => user.age >= 18); console.log(allAdult); // true // 6. find:根据ID查找用户 const targetUser = users.find(user => user.id === 2); console.log(targetUser); // 李四 // 7. reduce:计算所有用户年龄总和 const totalAge = users.reduce((sum, user) => sum + user.age, 0); console.log(totalAge); // 22+18+25=65 // 8. reduce进阶:按状态分组 const groupedUsers = users.reduce((obj, user) => { if (!obj[user.status]) obj[user.status] = []; obj[user.status].push(user); return obj; }, {}); console.log(groupedUsers); // {active: [张三, 王五], inactive: [李四]}
避坑要点:
  • ❌ 不要用forEach尝试终止循环(return无效),改用some/everyfor...of
  • reduce必须传初始值(第二个参数),否则空数组会报错,单元素数组直接返回该元素;
  • map不要用于无返回值的遍历(浪费性能),改用forEach
  • some/every是 “短路遍历”,找到结果立即终止,比forEach+ 判断更高效。

3. 特殊场景遍历

(1)for...in(不推荐遍历数组)

for...in设计初衷是遍历对象,遍历数组时会包含原型链属性,且索引为字符串类型:

javascript

运行

Array.prototype.foo = "原型属性"; const arr = [1, 2, 3]; for (const key in arr) { console.log(key); // 0,1,2,foo(包含原型属性) console.log(typeof key); // string(索引是字符串) }

结论:数组遍历绝对不要用for...in

(2)Array.from(遍历类数组 / 可迭代对象)

适合将 DOM 集合、arguments 等类数组对象转为数组并遍历:

javascript

运行

// 遍历DOM节点列表 const lis = document.querySelectorAll("li"); const liTexts = Array.from(lis, li => li.textContent); console.log(liTexts); // 所有li的文本内容 // 遍历字符串(可迭代对象) const str = "hello"; const charArr = Array.from(str, char => char.toUpperCase()); console.log(charArr); // ['H','E','L','L','O']

二、对象遍历:精准获取键值对

对象遍历的核心是 “区分自身属性 / 原型属性”“可枚举 / 不可枚举属性”“普通键 / Symbol 键”,以下按 “常用程度” 排序讲解。

1. 主流方案:Object.entries () + for...of(ES6+)

最推荐的对象遍历方式,无需过滤原型属性,直接获取键值对,语法简洁:

javascript

运行

const user = { name: "张三", age: 22, status: "active" }; // 遍历键值对 for (const [key, value] of Object.entries(user)) { console.log(`${key}: ${value}`); } // 结合解构+forEach Object.entries(user).forEach(([key, value]) => { console.log(`${key}: ${value}`); });

核心优势

  • 仅遍历对象自身可枚举属性,无需hasOwnProperty过滤;
  • 直接获取 [key, value],无需手动obj[key]取值;
  • 语法统一,与数组遍历风格一致。

2. 基础方案:for...in + hasOwnProperty

传统对象遍历方法,需手动过滤原型属性,否则会遍历到原型链上的可枚举属性:

javascript

运行

const user = { name: "张三", age: 22 }; Object.prototype.foo = "原型属性"; // 正确用法:过滤原型属性 for (const key in user) { if (user.hasOwnProperty(key)) { console.log(`${key}: ${user[key]}`); // 仅name、age } }

适用场景:仅兼容 ES5 的老旧项目,新项目优先用Object.entries()

3. 专项方案:按需求获取键 / 值

  • Object.keys(obj):获取自身可枚举键的数组;
  • Object.values(obj):获取自身可枚举值的数组;

javascript

运行

const user = { name: "张三", age: 22 }; // 获取所有键 const keys = Object.keys(user); // ['name', 'age'] // 获取所有值 const values = Object.values(user); // ['张三', 22] // 遍历键 keys.forEach(key => console.log(key)); // 遍历值 values.forEach(value => console.log(value));

4. 特殊场景:遍历不可枚举 / Symbol 属性

业务中极少用到,但面试常考,需掌握Object.getOwnPropertyNames()Object.getOwnPropertySymbols()

javascript

运行

// 定义不可枚举属性和Symbol键 const symKey = Symbol("id"); const obj = { name: "张三" }; // 定义不可枚举属性 Object.defineProperty(obj, "id", { value: 1001, enumerable: false // 不可枚举 }); // 定义Symbol键 obj[symKey] = "symbol-value"; // 1. 获取所有自身属性(含不可枚举,不含Symbol) const allKeys = Object.getOwnPropertyNames(obj); console.log(allKeys); // ['name', 'id'] // 2. 获取所有Symbol键 const symKeys = Object.getOwnPropertySymbols(obj); console.log(symKeys); // [Symbol(id)] // 3. 遍历所有自身属性(含不可枚举+Symbol) const allProps = [...allKeys, ...symKeys]; allProps.forEach(key => { console.log(`${key}: ${obj[key]}`); });

三、选型决策树(快速选对方法)

数组遍历选型

预览

查看代码

无返回值

新数组(映射)

新数组(筛选)

布尔值(存在性)

单个元素/索引

聚合值(求和/分组)

数组遍历

是否需要终止/跳过?

for循环 / for...of

是否需要返回值?

forEach

map

filter

some/every

find/findIndex

reduce

graph TD A[数组遍历] --> B{是否需要终止/跳过?} B -->|是| C[for循环 / for...of] B -->|否| D{是否需要返回值?} D -->|无返回值| E[forEach] D -->|新数组(映射)| F[map] D -->|新数组(筛选)| G[filter] D -->|布尔值(存在性)| H[some/every] D -->|单个元素/索引| I[find/findIndex] D -->|聚合值(求和/分组)| J[reduce]

无返回值

新数组(映射)

新数组(筛选)

布尔值(存在性)

单个元素/索引

聚合值(求和/分组)

数组遍历

是否需要终止/跳过?

for循环 / for...of

是否需要返回值?

forEach

map

filter

some/every

find/findIndex

reduce

豆包

你的 AI 助手,助力每日工作学习

对象遍历选型

预览

查看代码

生成失败,请重试

graph TD A[对象遍历] --> B{是否需要键值对?} B -->|是| C[Object.entries() + for...of] B -->|否| D{仅需键?} D -->|是| E[Object.keys()] D -->|否| F[Object.values()] A --> G{是否需遍历不可枚举/Symbol?} G -->|是| H[Object.getOwnPropertyNames() + Object.getOwnPropertySymbols()] G -->|否| I[主流方案]

生成失败,请重试

豆包

你的 AI 助手,助力每日工作学习

四、性能与最佳实践

1. 性能对比(10 万条数据测试)

方法执行时间(ms)适用场景
for 循环~5大数据量、需极致性能
for...of~8中等数据量、需简洁可控
forEach~10小数据量、无终止需求
map/filter~12小数据量、需返回新数组
for...in(数组)~50绝对避免

2. 最佳实践

  • ✅ 业务代码优先保证可读性,大数据量(10 万 +)再优化性能;
  • ✅ 数组遍历优先用map/filter/some/every/reduce(语义化),而非 forEach + 手动逻辑;
  • ✅ 对象遍历优先用Object.entries(),替代for...in
  • ✅ 避免在遍历中修改原数组(如 splice/push),易导致索引错乱;
  • ✅ 遍历嵌套数据时,优先扁平化(如flatMap)后再遍历,减少嵌套层级。

总结

  1. 数组遍历的核心是 “匹配业务意图”:需终止用for/for...of,需映射用map,需筛选用filter,需聚合用reduce
  2. 对象遍历优先选择Object.entries() + for...of,无需手动过滤原型属性,语法简洁;
  3. 选择遍历方法的核心原则:语义化 > 简洁性 > 性能,仅在大数据量场景下优先考虑性能。

掌握这些遍历方法,不仅能写出更优雅的代码,更能避免常见的边界错误。记住:没有 “最好” 的方法,只有 “最适合” 当前场景的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1131582.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NAT技术:互联网连接的隐形桥梁

目录 一、NAT 技术&#xff1a;从地址短缺到连接复用 1、背景&#xff1a;IPv4 地址枯竭与私有地址的诞生 2、基本 NAT&#xff08;Basic NAT&#xff09;&#xff1a;一对一地址转换 工作原理&#xff1a; 示例&#xff1a; 局限性&#xff1a; 3、NAPT&#xff08;Net…

Redis的两个小错误

说明&#xff1a;本文介绍关于自己遇到的 Redis 相关的两个小错误 问题一&#xff1a;配置没生效 在 Linux 中启动 redis 服务&#xff0c;发现配置文件中的设置没有起作用&#xff0c;设置了密码和可访问地址&#xff0c;没用 发现没起作用&#xff0c;我在服务器上启动 red…

深度学习计算机毕设之基于人工智能python-CNN卷积神经网络对土豆疾病识别基于python-CNN卷积神经网络对土豆疾病识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

mysql如何创建用户并且授权

在 MySQL 中可以使用以下步骤创建用户&#xff1a; 1.使用管理员账户登录到 MySQL&#xff1a; - 打开命令行终端&#xff0c;输入以下命令以管理员身份登录 MySQL&#xff08;假设 MySQL 安装在默认位置且管理员用户为root&#xff0c;密码为your_root_password&#xff09;&a…

Springboot校园二手交易平台lca16(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表项目功能&#xff1a;商品分类,用户,二手商品开题报告内容一、选题背景与意义&#xff08;一&#xff09;选题背景随着高等教育的普及和校园生活的丰富多彩&#xff0c;大学生在日常学习和生活中产生了大量的闲置物品&#xff0c;如书籍、电子产品、生活用品等…

深度学习毕设项目:基于python-CNN卷积神经网络的水果识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

NSSCTF2026年1月8日每日一练之[第五空间 2021]WebFTP

开启环境&#xff0c;进入页面得到先进行目录扫描 python dirsearch.py -u http://node4.anna.nssctf.cn:26891/扫描得到看到phpinfo.php&#xff0c;猜测可能存在php版本等相关敏感信息&#xff0c;访问一下搜索ctf或者flag&#xff0c;可以得到最终结果得到最终结果 NSSCTF{b…

ADVANCE Day44

浙大疏锦行 &#x1f4d8; Day 44 实战作业 (极速版)&#xff1a;ResNet 与 迁移学习 1. 作业综述 核心目标&#xff1a; 迁移学习&#xff1a;学会调用 ImageNet 预训练的 ResNet18 模型&#xff0c;将其知识迁移到 CIFAR-10 任务上。策略对比&#xff1a;亲手实验 冻结骨…

深度学习毕设项目:基于python-CNN卷积神经网络对土豆疾病识别基于python-CNN卷积神经网络对土豆疾病识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

剪切板推荐,pastemate代替win系统自带的

通过网盘分享的文件&#xff1a;pastemate剪切板.rar 链接: https://pan.baidu.com/s/1InJIvHtkC9tQqMgQiq-jhw?pwd5668 提取码: 5668 win自带的有上限&#xff0c;也不会同步&#xff0c;放弃了&#xff0c;用这个

LangGraph1.0实战:构建自动邮件处理智能体,大模型应用开发指南

本文详细介绍了如何使用LangGraph1.0构建自动邮件处理智能体&#xff0c;展示了状态管理、节点、边、条件路由和中断机制等核心技术的实战应用。通过定义智能体状态、编写节点函数、构建智能体图和测试验证&#xff0c;实现了一个能够自动分类邮件、处理Bug报告、搜索知识库生成…

DeepSeek+Ollama+AnythingLLM搭建本地知识库,打造你的私人AI管家(建议收藏)

本文详细介绍了使用DeepSeek、Ollama和AnythingLLM搭建本地知识库的全过程&#xff0c;包括软件安装、模型配置、文档上传和智能问答功能。教程特别强调了本地部署对隐私保护的优势&#xff0c;并提供了文档类型准备和嵌入模型配置等实用建议&#xff0c;帮助用户打造专属AI助理…

从代码到上线 3 分钟:我如何用平台工程思路,彻底告别繁琐的 K8s 运维

“在我电脑上明明是好的啊&#xff1f;”这句话我不知道说过多少次&#xff0c;也听过多少次。作为一名开发者&#xff0c;我大部分的精力本该在创造业务价值&#xff0c;但现实却常常是&#xff0c;大量时间被浪费在了写代码之外的所有事情上。我开始反思&#xff0c;为什么在…

深度学习毕设项目:通过python_CNN卷积神经网络对鸡蛋是否破损识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

AI大模型岗位薪资真相:多少年包能拿到?普通人如何破局?_AI持续爆火,相关岗位薪资到底达到了多少

文章分析AI相关岗位薪资情况&#xff0c;指出高薪岗位(最高100万年包)主要面向博士海归或博士985人才&#xff0c;能拿到此等薪资的人凤毛麟角。同时提醒职场风险&#xff0c;建议提前做好准备。后半部分介绍了JMeter常用插件的安装及使用方法。 “AI相关岗位薪资” 随着AI持续…

深度学习计算机毕设之基于python-CNN卷积神经网络的水果识别基于python-CNN卷积神经网络的水果识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

【金仓数据库】ksql 指南(六)—— 创建与管理用户和权限(KingbaseES 安全控制核心)

引言 完成数据库&#xff0c;表&#xff0c;索引这些核心对象的运作之后&#xff0c;“用户与权限控制”就成了保障 KingbaseES 数据安全的重点所在&#xff0c;经由细致的用户运作和权限分配&#xff0c;可以规避未授权访问以及误操作之类的风险&#xff0c;比如普通用户就无…

【毕业设计】基于深度学习python卷积网络对甘蔗叶子病识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

高效收集并分享活动精彩瞬间!!组织者必看

周末逃离城市的喧嚣&#xff0c;和朋友们一起参加了一场超治愈的寺院茶会 &#x1f375; 心情真的像被洗过一样&#xff0c;平静又温柔。 在古色古香的寺院里&#xff0c;听着檐角的风铃&#xff0c;看着袅袅的茶烟&#xff0c;闻着清雅的茶香&#xff0c;感受着那份难得的闲适…