JavaScript 遍历 JSON 列表(数组)的 5 种常用方法详解
在 Web 开发中,JSON(JavaScript Object Notation)因其轻量级、易读易写的特性,成为了数据交换的主流格式,我们经常会从服务器接收到一个 JSON 格式的列表(在 JavaScript 中表现为一个数组),然后需要在客户端对这个列表进行遍历,以提取、展示或处理其中的数据。
本文将详细介绍在 JavaScript 中遍历 JSON 列表的 5 种常用方法,从最基础的 for
循环到现代函数式编程的 forEach
、for...of
、map
和 filter
,并分析它们各自的适用场景。
准备工作:一个示例 JSON 列表
为了方便演示,我们首先定义一个包含用户信息的 JSON 列表(数组)。
const userList = [ { id: 1, name: 'Alice', age: 25, city: 'New York' }, { id: 2, name: 'Bob', age: 30, city: 'London' }, { id: 3, name: 'Charlie', age: 35, city: 'Paris' }, { id: 4, name: 'Diana', age: 28, city: 'Tokyo' } ];
我们的目标就是遍历 userList
数组,访问到其中的每一个用户对象。
经典的 for 循环
这是最传统、最基础的遍历方式,几乎所有编程语言都支持,它通过一个索引变量(i
)来访问数组的每一个元素。
代码示例:
console.log('--- 使用 for 循环遍历 ---'); for (let i = 0; i < userList.length; i++) { const user = userList[i]; console.log(`ID: ${user.id}, 姓名: ${user.name}, 城市: ${user.city}`); }
优点:
- 兼容性最好:可以在所有 JavaScript 环境中运行,包括非常古老的浏览器。
- 灵活性强:可以方便地获取当前元素的索引(
i
),并且可以在循环中自由控制循环的起始和结束条件。
缺点:
- 代码冗长:需要手动管理索引变量
i
,代码看起来不够简洁。 - 容易出错:手写的循环条件容易出错(
<=
代替<
)。
for...in 循环
for...in
循环用于遍历对象的可枚举属性,对于数组,它会遍历数组的索引(字符串形式),而不是元素本身。
代码示例:
console.log('\n--- 使用 for...in 循环遍历 ---'); for (const index in userList) { // 注意:index 是字符串类型的索引 const user = userList[index]; console.log(`索引: ${index}, ID: ${user.id}, 姓名: ${user.name}`); }
优点:
- 可以遍历对象和数组的索引。
缺点:
- 遍历的是索引:它获取的是数组的键(索引),而不是值,需要通过
array[index]
来访问元素,稍显不便。 - 会遍历原型链上的属性:如果数组被修改(添加了自定义属性),
for...in
也会遍历这些不希望被访问到的属性。不推荐使用for...in
来遍历数组,它更适合遍历普通对象。
forEach() 方法
forEach()
是 JavaScript 数组的一个内置方法,它为数组中的每个元素执行一次提供的函数,这是函数式编程思想的体现。
代码示例:
console.log('\n--- 使用 forEach() 方法遍历 ---'); userList.forEach(function(user, index) { // 第一个参数是当前元素,第二个参数是当前索引(可选) console.log(`索引: ${index}, ID: ${user.id}, 姓名: ${user.name}`); }); // 使用箭头函数可以更简洁 userList.forEach((user, index) => { console.log(`索引: ${index}, 城市: ${user.city}`); });
优点:
- 代码简洁:语法清晰,将循环体封装在一个回调函数中,避免了索引变量的管理。
- 不易出错:无需关心循环的边界条件,由 JavaScript 引擎自动处理。
- 可读性高:意图明确,对每个元素做某事”。
缺点:
- 无法使用
break
或continue
:一旦开始,必须遍历完所有元素,无法中途跳出循环。 - 异步处理麻烦:在
forEach
中使用async/await
不会按预期工作,因为它不会等待每个异步操作完成。
for...of 循环
for...of
是 ES6 引入的一种新的循环语法,专门用于遍历可迭代对象(如数组、字符串、Map、Set 等),它直接获取元素的值,是遍历数组最推荐的方式之一。
代码示例:
console.log('\n--- 使用 for...of 循环遍历 ---'); for (const user of userList) { // user 直接就是数组中的元素对象 console.log(`ID: ${user.id}, 姓名: ${user.name}, 年龄: ${user.age}`); }
优点:
- 语法最简洁直观:直接获取元素值,无需关心索引。
- 性能优秀:在现代 JavaScript 引擎中,
for...of
的性能通常接近甚至优于传统的for
循环。 - 可以与
break
、continue
和return
配合使用:可以灵活地控制循环流程。
缺点:
- 无法直接获取索引:如果需要在遍历时同时获取索引,需要借助
Array.prototype.entries()
等方法。
map() 和 filter() 等高阶函数
除了遍历,我们经常还需要在遍历的同时对数据进行转换或筛选,这时,map()
和 filter()
等高阶函数就派上用场了,它们虽然不完全等同于“遍历”,但核心逻辑是遍历数组。
map()
:转换数据
当你需要创建一个由原数组元素经过处理后组成的新数组时,使用 map()
。
示例:提取所有用户的姓名
console.log('\n--- 使用 map() 提取姓名列表 ---'); const names = userList.map(user => user.name); console.log(names); // 输出: ['Alice', 'Bob', 'Charlie', 'Diana']
filter()
:筛选数据
当你需要根据条件筛选出数组中满足要求的元素时,使用 filter()
。
示例:筛选出年龄大于 30 的用户
console.log('\n--- 使用 filter() 筛选年长用户 ---'); const olderUsers = userList.filter(user => user.age > 30); console.log(olderUsers); // 输出: // [ // { id: 3, name: 'Charlie', age: 35, city: 'Paris' } // ]
优点:
- 声明式编程:你只需要声明“做什么”,而不需要关心“怎么做”,代码更易于理解和维护。
- 链式调用:可以轻松地将多个操作组合在一起,形成流畅的代码链。
总结与最佳实践
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
for 循环 |
兼容性好,灵活,可 break |
冗长,易出错 | 需要精细控制循环流程,或兼容性要求极高的环境。 |
for...in |
可遍历对象索引 | 遍历索引而非值,会遍历原型链 | 不推荐用于数组遍历,更适合遍历普通对象的键。 |
forEach() |
代码简洁,可读性高 | 无法 break ,异步处理麻烦 |
简单地遍历数组并对每个元素执行操作,无需中断。 |
for...of |
语法简洁,性能好,可 break |
无法直接获取索引 | 现代 JavaScript 中遍历数组的首选,简单高效。 |
map() /filter() |
声明式,可链式调用 | 主要用于转换/筛选,非纯遍历 | 需要对数组进行转换、筛选、聚合等操作时。 |
最终建议:
- 日常开发中,优先使用
for...of
循环,它在简洁性、性能和功能性之间取得了最佳平衡。 - 如果只是想对数组中的每个元素执行一个副作用操作(如打印、更新 DOM),并且不需要中途退出,
forEach()
是一个不错的选择。 - 如果需要对数据进行转换或筛选,请毫不犹豫地使用
map()
和
还没有评论,来说两句吧...