当前位置: 首页 > news >正文

数组和对象常用遍历方式

数组遍历方式

  • for循环

  • for...of

  • forEach

  • map

  • filter

  • reduce

  • some / every

  • find / findIndex

  • for...in(不推荐,但可以说避免使用)

对象遍历方式

  • for...in

  • Object.keys()

  • Object.values()

  • Object.entries()

  • Object.getOwnPropertyNames()

  • Reflect.ownKeys()

  • for...of + Object.entries()

每个场景都要简短说明为什么选这个方法。

注意代码格式,保持清晰。

由于回答可能较长,我将组织成有标题的形式,但避免markdown过多层级。

以下是常用数组和对象遍历 API 的实际使用场景,每个都给出了典型示例和选择理由。


一、数组遍历

1.for循环

场景:需要在遍历过程中动态修改数组长度、提前跳出(break),或者对性能要求极高的场合。

javascript

// 场景:删除数组中所有值为 null 的元素(从后往前删除,避免索引错位) let arr = [1, null, 2, null, 3]; for (let i = arr.length - 1; i >= 0; i--) { if (arr[i] === null) { arr.splice(i, 1); } } // arr -> [1, 2, 3]

2.for...of

场景:只需要元素值,并可能提前退出(break/continue),代码简洁。

javascript

// 场景:检查数组中是否包含某个值,一旦找到就停止 const ids = [101, 205, 307, 409]; let targetId = 307; let found = false; for (const id of ids) { if (id === targetId) { found = true; break; } }

3.forEach

场景:单纯执行副作用(如打印、更新外部状态),不需要中断循环。

javascript

// 场景:批量更新页面上的元素内容 const elements = document.querySelectorAll('.item'); elements.forEach((el, index) => { el.textContent = `第 ${index + 1} 项`; });

4.map

场景:从原数组生成一个新数组,且新数组长度相同。

javascript

// 场景:将用户对象数组转换为只包含用户名的数组 const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const names = users.map(user => user.name); // names -> ['Alice', 'Bob']

5.filter

场景:根据条件筛选出子集。

javascript

// 场景:获取所有已完成的任务 const tasks = [ { title: '学习JS', done: true }, { title: '写报告', done: false } ]; const completed = tasks.filter(task => task.done);

6.reduce

场景:将数组归约为单个值(累加、合并对象、分组等)。

javascript

// 场景:统计商品总价 const cart = [ { name: '苹果', price: 5, count: 2 }, { name: '香蕉', price: 3, count: 3 } ]; const total = cart.reduce((sum, item) => sum + item.price * item.count, 0); // total -> 19

7.some/every

场景:快速判断数组是否满足某些条件。

javascript

// some: 检查数组中是否存在未支付订单 const orders = [ { id: 1, paid: true }, { id: 2, paid: false } ]; const hasUnpaid = orders.some(order => !order.paid); // true // every: 检查所有学生是否都及格 const scores = [85, 92, 78, 88]; const allPass = scores.every(score => score >= 60); // true

8.find/findIndex

场景:查找第一个符合条件的元素或其索引。

javascript

// 场景:根据 id 查找用户对象 const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const user = users.find(u => u.id === 2); // user -> { id: 2, name: 'Bob' }

9.for...in(避免用于数组)

不推荐,因为它会遍历数组对象上所有可枚举属性(包括原型链),且不保证顺序。
如果误用可能造成问题,例如:

javascript

Array.prototype.custom = 'foo'; const arr = [1, 2]; for (let i in arr) { console.log(i); // 输出 "0", "1", "custom" }

二、对象遍历

1.for...in

场景:需要遍历对象自身及原型链上的可枚举属性(通常配合hasOwnProperty过滤)。

javascript

// 场景:复制对象自身属性(不包括原型) const source = { a: 1, b: 2 }; const target = {}; for (let key in source) { if (source.hasOwnProperty(key)) { target[key] = source[key]; } }

2.Object.keys()

场景:获取对象自身可枚举属性名,然后结合数组方法处理。

javascript

// 场景:遍历对象并执行操作 const config = { host: 'localhost', port: 8080, ssl: false }; Object.keys(config).forEach(key => { console.log(`${key}: ${config[key]}`); });

3.Object.values()

场景:只需要对象的值。

javascript

// 场景:计算所有学生成绩的总分 const scores = { math: 95, english: 88, science: 92 }; const total = Object.values(scores).reduce((sum, score) => sum + score, 0); // total -> 275

4.Object.entries()

场景:同时需要键和值,是最常用的对象遍历方式。

javascript

// 场景:将对象转换为查询字符串 const params = { search: 'js', page: 1, limit: 10 }; const queryString = Object.entries(params) .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) .join('&'); // queryString -> "search=js&page=1&limit=10"

5.Object.getOwnPropertyNames()

场景:需要遍历对象的不可枚举属性(如某些内置属性)。

javascript

// 场景:获取对象所有自身属性(包括不可枚举的) const obj = {}; Object.defineProperty(obj, 'hidden', { value: 42, enumerable: false }); console.log(Object.getOwnPropertyNames(obj)); // ['hidden']

6.Reflect.ownKeys()

场景:需要完整获取对象所有自身属性键,包括 Symbol 类型。

javascript

// 场景:深拷贝对象时保留 Symbol 属性 const sym = Symbol('id'); const obj = { name: 'foo', [sym]: 123 }; const clone = {}; Reflect.ownKeys(obj).forEach(key => { clone[key] = obj[key]; }); console.log(clone); // { name: 'foo', [sym]: 123 }

7.for...of+Object.entries()

场景:需要遍历对象的同时可以随时中断(break)。

javascript

// 场景:查找对象中第一个值大于 100 的键值对 const data = { a: 50, b: 120, c: 80 }; let foundKey = null; for (const [key, value] of Object.entries(data)) { if (value > 100) { foundKey = key; break; } } // foundKey -> 'b'

选择总结

场景需求推荐 API
数组需中断、高性能forfor...of
数组执行副作用,不中断forEach
数组转换(映射、筛选、归约)mapfilterreduce
数组条件判断someeveryfind
对象遍历自身可枚举属性Object.entries()+forEach/for...of
对象只需键或值Object.keys()Object.values()
对象需包含不可枚举或 Symbol 属性Object.getOwnPropertyNames()Reflect.ownKeys()
对象需要中途跳出for...of+Object.entries()
http://www.jsqmd.com/news/523634/

相关文章:

  • 记录复现多模态大模型论文OPERA的一周工作(2)
  • 装了OpenClaw却不会用?先搞懂这23个AI基础概念
  • Fish Speech 1.5语音合成绿色计算:功耗监控与能效比优化实践
  • 用GLM-OCR搭建本地文档处理工具:发票/合同/证件信息一键抽取
  • TikTok运营智能助手达人精灵优惠码推荐 | 网页端+插件端无缝协同 - 麦麦唛
  • 大核心优势!这家发稿平台,央媒资源+达人矩阵+多端操作一站式搞定 - 博客湾
  • 别再死记硬背公式了!用MATLAB手把手教你玩转根轨迹,分析系统稳定性
  • 2026年高端度假酒店精选:必住口碑之选,桐庐富春江畔静谧度假酒店公司推荐 - 品牌推荐官
  • Steam交易效率革命:从手动操作到智能批量化的终极指南
  • 电感器原理、选型与电源应用全解析
  • 基于ADXL345三轴加速度传感器的计步器实现
  • 自动驾驶伦理测试的生死簿:软件测试从业者的专业战场
  • OFA图像字幕模型实战:为AR眼镜实时画面生成英文语音旁白
  • 通义千问2.5-7B-Instruct效果展示:代码生成与数学推理实测
  • AudioSeal Pixel Studio实操手册:检测报告PDF导出与API对接方法
  • 树莓派音频配置实战:aplay声卡识别问题排查指南
  • 傅立叶变换不只是信号处理:看FNO如何用它革新AI求解物理方程
  • 嵌入式ByteBuffer库:轻量级字节缓冲区设计与实践
  • 脑电情感计算实战(EEG) (上):从SEED数据集到特征工程的探索之路
  • Citra全攻略:零基础上手3DS游戏模拟的高效解决方案
  • TWDS系统在重载铁路轮对动态检测中的关键技术解析
  • Pi0具身智能v1功能体验:Toast Task场景完整操作流程
  • 为什么你的Dify异步节点总超时?揭秘插件下载源篡改风险、npm proxy冲突与install-hooks绕过方案
  • 元宇宙大饥荒:百万虚拟人集体饿死
  • 新手必看:Gemma-3-12B-IT镜像部署踩坑指南与优化技巧
  • 【ROS】noetic-moveit与UR5模型实战:从环境搭建到可视化控制
  • 知识蒸馏在图像缺陷检测中的创新应用:教师-学生模型协同优化策略
  • Arduino ESP32安装卡住?教你手动下载并替换依赖包(Windows版)
  • DanKoe 视频笔记:个人品牌构建:如何创建最有利可图的领域——你自己
  • 5分钟搞定dbt core与BigQuery适配器安装(附常见报错解决方案)