JavaScript中JSON数据的处理全攻略
在Web开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易读、易解析的特性,已成为前后端数据交互的“通用语言”,无论是从服务器获取API响应,还是在本地存储配置信息,都离不开对JSON数据的处理,本文将系统介绍JavaScript中JSON数据的处理方法,包括解析、序列化、遍历、修改及高级技巧,帮助开发者高效操作JSON数据。
JSON与JavaScript对象的区别
在处理之前,需明确JSON与JavaScript对象的本质区别:
- JSON:一种独立于语言的文本格式,要求严格——键必须用双引号包裹,值仅支持字符串、数字、布尔值、null、数组及对象(不支持函数、undefined、Date等特殊类型)。
- JavaScript对象:JS语言的内置类型,键可使用单引号/双引号/无引号,值支持任意JS数据类型(包括函数、Symbol等)。
// 合法的JSON
{"name": "Alice", "age": 25, "hobbies": ["reading", "coding"]}
// 非法的JSON(键用单引号/包含函数)
{'name': 'Bob', 'sayHi': function() { console.log('Hi'); }}
JSON字符串的解析:将JSON文本转为JS对象
当从服务器获取数据(如fetch、XMLHttpRequest的响应)或读取本地存储的JSON字符串时,需先将其转换为JavaScript对象才能操作,核心方法是JSON.parse()。
基本用法
JSON.parse()接收一个JSON字符串,返回对应的JS对象/数组。
const jsonString = '{"name": "Alice", "age": 25, "hobbies": ["reading", "coding"]}';
const obj = JSON.parse(jsonString);
console.log(obj.name); // "Alice"
console.log(obj.hobbies[0]); // "reading"
处理复杂嵌套结构
JSON支持多层嵌套,JSON.parse()会自动解析为对应的JS对象/数组嵌套结构。
const nestedJson = '{"user": {"id": 1, "profile": {"city": "Beijing", "contacts": ["email@example.com"]}}}';
const nestedObj = JSON.parse(nestedJson);
console.log(nestedObj.user.profile.city); // "Beijing"
console.log(nestedObj.user.profile.contacts[0]); // "email@example.com"
安全注意事项:避免“JSON注入”
直接解析不可信的JSON字符串可能导致安全风险(如原型污染),建议:
- 验证数据来源:确保JSON字符串来自可信的服务器或本地存储。
- 使用reviver函数过滤敏感数据(后文详述)。
JavaScript对象的序列化:将JS对象转为JSON字符串
当前后端需要发送数据到服务器,或本地存储JS对象时,需将其转换为JSON字符串,核心方法是JSON.stringify()。
基本用法
JSON.stringify()接收一个JS对象,返回JSON字符串。
const obj = { name: "Bob", age: 30, hobbies: ["swimming", "traveling"] };
const jsonString = JSON.stringify(obj);
console.log(jsonString); // '{"name":"Bob","age":30,"hobbies":["swimming","traveling"]}'
处理特殊数据类型
JSON.stringify()会自动处理特殊类型:
- 函数、Symbol、undefined:会被忽略(不包含在字符串中)。
- Date对象:会被转换为字符串(调用
toISOString())。 - NaN、Infinity:会被转换为
null。
const objWithSpecial = {
name: "Charlie",
age: 28,
sayHi: function() { console.log("Hi"); }, // 函数被忽略
birth: new Date("1995-01-01"), // 转换为ISO字符串
invalid: NaN, // 转换为null
};
console.log(JSON.stringify(objWithSpecial));
// '{"name":"Charlie","age":28,"birth":"1995-01-01T00:00:00.000Z","invalid":null}'
高级用法:replacer与space参数
(1)replacer:过滤或转换数据
replacer可以是函数或数组,用于控制哪些属性被序列化,或修改值。
- 作为数组:指定需要序列化的属性名(白名单)。
const obj = { name: "David", age: 35, password: "123456" }; const jsonStr = JSON.stringify(obj, ["name", "age"]); // 仅保留name和age console.log(jsonStr); // '{"name":"David","age":35}' - 作为函数:遍历每个属性,返回值会替换原值(返回
undefined则忽略该属性)。const obj = { name: "Eve", age: 40, salary: 10000 }; const jsonStr = JSON.stringify(obj, (key, value) => { if (key === "salary") return value * 1.2; // 加薪20% if (key === "age") return undefined; // 忽略age return value; }); console.log(jsonStr); // '{"name":"Eve","salary":12000}'
(2)space:格式化输出
space参数用于美化JSON字符串(调试或展示时使用),可以是数字(缩空格数)或字符串(缩进字符)。
const obj = { name: "Frank", hobbies: ["music", "sports"] };
const prettyJson = JSON.stringify(obj, null, 2); // 缩进2个空格
console.log(prettyJson);
/*
{
"name": "Frank",
"hobbies": [
"music",
"sports"
]
}
*/
JSON数据的遍历与修改
解析JSON后,得到的是普通的JS对象/数组,可直接通过JS语法遍历和修改。
遍历JSON对象
(1)for...in循环:遍历可枚举属性
const obj = { name: "Grace", age: 22, city: "Shanghai" };
for (const key in obj) {
if (obj.hasOwnProperty(key)) { // 确保是对象自身的属性
console.log(`${key}: ${obj[key]}`);
}
}
// 输出:
// name: Grace
// age: 22
// city: Shanghai
(2)Object.keys() + forEach:获取键后遍历
Object.keys(obj).forEach(key => {
console.log(`${key}: ${obj[key]}`);
});
(3)for...of + Object.entries():遍历键值对
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`);
}
遍历JSON数组
使用forEach、for...of、map等数组方法。
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
];
// forEach遍历
users.forEach(user => {
console.log(`ID: ${user.id}, Name: ${user.name}`);
});
// map提取数据
const names = users.map(user => user.name);
console.log(names); // ["Alice", "Bob"]
修改JSON数据
直接通过赋值或数组方法修改解析后的JS对象/数组(注意:JSON本身是不可变的,修改的是其JS副本)。
const user = { id: 1, name: "Henry", tags: ["VIP", "active"] };
// 修改对象属性
user.name = "Henry Updated";
user.tags.push("premium"); // 修改数组
// 添加新属性
user.email = "henry@example.com";
console.log(user);
// {id: 1, name: "Henry Updated", tags: ["VIP", "active", "premium"], email: "henry@example.com"}
JSON处理的进阶技巧
使用reviver函数处理日期
JSON.parse()的reviver参数可用于恢复被序列化的Date对象。
const userWithDate = {
name: "Ivy",
loginTime: new Date().toISOString(), // 序列化为字符串
};
// 序列化
const jsonStr = JSON.stringify(userWithDate);
console.log(jsonStr); // '{"name":"Ivy","loginTime":"2023-10-01T12:00:00.000Z"}'
// 解析时恢复Date对象
const parsedUser = JSON.parse(jsonStr, (key, value) => {
if (key === "loginTime") return new Date(value);
return value;
});
console.log(parsedUser.loginTime instanceof Date); // true
console.log(parsedUser.loginTime); //


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