JavaScript 遍历 JSON 字符串的完整指南
在 Web 开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,被广泛应用,我们经常需要从服务器接收 JSON 格式的数据,这些数据通常以字符串的形式存在,要在 JavaScript 中处理这些数据,第一步也是最重要的一步,就是将其转换为 JavaScript 对象或数组,然后进行遍历,本文将详细讲解如何遍历 JSON 字符串,从基础到进阶,并提供最佳实践。
第一步:解析 JSON 字符串
在遍历之前,我们必须明确一个核心概念:JavaScript 无法直接遍历一个 JSON 字符串,字符串只是一个文本,我们需要使用 JSON.parse() 方法将其解析成一个原生的 JavaScript 对象或数组。
// 这是一个 JSON 字符串
const jsonString = '{"name": "张三", "age": 30, "city": "北京", "hobbies": ["阅读", "旅行", "编程"]}';
// 使用 JSON.parse() 将其转换为 JavaScript 对象
const dataObject = JSON.parse(jsonString);
console.log(dataObject);
// 输出: { name: '张三', age: 30, city: '北京', hobbies: [ '阅读', '旅行', '编程' ] }
重要提示: jsonString 的格式不正确(使用了单引号、属性名没有加引号或多了逗号),JSON.parse() 会抛出 SyntaxError,在解析前最好确保数据来源可靠,或者使用 try...catch 进行错误处理。
const badJsonString = "{name: '李四', age: 25}"; // 这是一个无效的 JSON 字符串
try {
const parsedData = JSON.parse(badJsonString);
console.log(parsedData);
} catch (error) {
console.error("JSON 解析失败:", error.message);
// 输出: JSON 解析失败: Unexpected token n in JSON at position 1
}
完成解析后,我们就可以根据解析后的数据类型(对象或数组)选择合适的遍历方法了。
遍历 JSON 对象
如果解析后的数据是一个 JavaScript 对象(),我们有以下几种常用方法来遍历它的属性。
for...in 循环
for...in 循环专门用于遍历对象可枚举的属性(包括原型链上的属性),它会遍历出对象的键名。
const dataObject = JSON.parse(jsonString);
for (const key in dataObject) {
// 使用 hasOwnProperty() 来确保只遍历对象自身的属性,而不是从原型链继承的
if (dataObject.hasOwnProperty(key)) {
const value = dataObject[key];
console.log(`键: ${key}, 值: ${value}`);
}
}
输出:
键: name, 值: 张三
键: age, 值: 30
键: city, 值: 北京
键: hobbies, 值: 阅读,旅行,编程
优点:
- 语法简洁,专门用于遍历对象。
- 可以遍历对象原型链上的属性(尽管通常不推荐这么做)。
缺点:
- 遍历顺序不确定(在现代引擎中,大致会按插入顺序,但不能完全依赖)。
- 会遍历到原型链上的属性,需要配合
hasOwnProperty()过滤。
Object.keys() + forEach / for...of
Object.keys() 方法返回一个包含对象自身所有可枚举属性键名的数组,然后我们可以对这个数组进行遍历,从而获取每个键和对应的值。
const dataObject = JSON.parse(jsonString);
// 获取所有键名组成的数组
const keys = Object.keys(dataObject);
// 方法1: 使用 forEach
keys.forEach(key => {
const value = dataObject[key];
console.log(`键: ${key}, 值: ${value}`);
});
// 方法2: 使用 for...of
for (const key of keys) {
const value = dataObject[key];
console.log(`键: ${key}, 值: ${value}`);
}
这两种方法的输出结果与 for...in 类似,但它们不会遍历原型链上的属性,且遍历顺序更有保障(遵循数组顺序)。
Object.entries() + forEach / for...of
这是现代 JavaScript 中最推荐、最优雅的方式之一。Object.entries() 方法返回一个数组,其中每个元素都是 [key, value] 形式的数组,这让我们可以一次性同时拿到键和值。
const dataObject = JSON.parse(jsonString);
// 获取 [key, value] 对组成的数组
const entries = Object.entries(dataObject);
// 方法1: 使用 forEach
entries.forEach(([key, value]) => {
// 使用数组解构,直接获取 key 和 value
console.log(`键: ${key}, 值: ${value}`);
});
// 方法2: 使用 for...of
for (const [key, value] of entries) {
console.log(`键: ${key}, 值: ${value}`);
}
优点:
- 代码最简洁,可读性最高。
- 一次性获取键和值,避免二次查找。
- 不会遍历原型链上的属性。
遍历 JSON 数组
JSON 字符串解析后是一个 JavaScript 数组([]),'[{"id": 1}, {"id": 2}]',那么我们有以下方法。
经典 for 循环
这是最基础、性能最高的遍历方式,适用于任何场景。
const jsonArray = [
{ id: 1, name: "项目 A" },
{ id: 2, name: "项目 B" },
{ id: 3, name: "项目 C" }
];
for (let i = 0; i < jsonArray.length; i++) {
const element = jsonArray[i];
console.log(`索引: ${i}, 元素:`, element);
}
优点:
- 性能最优。
- 可以通过索引
i访问,方便进行一些基于索引的操作。
缺点:
- 语法相对繁琐。
- 容易因手误写成
i =<等错误。
for...of 循环
这是遍历数组最现代、最推荐的方式,它简洁、易读,并且可以正确处理各种可迭代对象。
const jsonArray = [
{ id: 1, name: "项目 A" },
{ id: 2, name: "项目 B" },
{ id: 3, name: "项目 C" }
];
for (const element of jsonArray) {
console.log("元素:", element);
}
优点:
- 语法极其简洁,可读性高。
- 专注于元素本身,无需关心索引。
- 是 ES6 引入的标准特性,兼容性良好。
Array.prototype.forEach()
forEach 方法为数组的每个元素执行一次提供的函数,它非常适合执行带有副作用的操作(如打印、修改外部变量等)。
const jsonArray = [
{ id: 1, name: "项目 A" },
{ id: 2, name: "项目 B" },
{ id: 3, name: "项目 C" }
];
jsonArray.forEach((element, index) => {
console.log(`索引: ${index}, 元素:`, element);
});
优点:
- 函数式编程风格,代码清晰。
- 方便地同时获取元素和它的索引。
缺点:
- 不能直接使用
break或continue来中断循环。 - 在某些旧版浏览器中可能需要 polyfill。
综合场景:嵌套 JSON 的遍历
现实中的 JSON 数据往往是嵌套的,一个用户对象中包含一个地址数组,这时,我们需要将上述方法结合使用,通常采用递归的方式。
const nestedJsonString = `
{
"user": {
"id": 101,
"username": "dev_user",
"roles": ["admin", "editor"],
"address": {
"street": "科技路 1 号",
"city": "上海"
}
}
}
`;
const data = JSON.parse(nestedJsonString);
function traverse(obj) {
// 检查是否为对象(且不是 null,因为 typeof null 也是 'object')
if (typeof obj === 'object' && obj !== null) {
// 如果是数组,则用 for...of 遍历
if (Array.isArray(obj)) {
for (const item of obj) {
traverse(item); // 递归遍历数组中的每一项
}
}
// 如果是对象,则用 for...in 或 Object.entries 遍历
else {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(`发现


还没有评论,来说两句吧...