JavaScript中JSON数据的处理全指南
在Web开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易于人阅读和编写、易于机器解析和生成,已成为前后端数据交互的核心格式,JavaScript作为前端开发的主要语言,提供了原生的JSON处理API,同时结合现代框架和工具,可以高效地完成JSON数据的解析、序列化、操作及校验等任务,本文将系统介绍JavaScript中JSON数据的处理方法,从基础操作到高级技巧,助你全面JSON处理技能。
JSON与JavaScript对象的区别与联系
在处理JSON之前,需明确JSON与JavaScript对象(Object)的关系:
- JSON是一种独立于语言的文本格式,语法规则严格:
- 键必须用双引号包裹,不能用单引号或无引号;
- 值仅支持基本数据类型(字符串、数字、布尔值、null)、数组、有序对象;
- 不能包含函数、
undefined、日期对象等特殊类型。
- JavaScript对象是JS语言的内置类型,语法更灵活:键可单引号/双引号/无引号,值可以是任意JS类型(如函数、
Date对象等)。
JSON是JavaScript对象的“子集”,也是其“字符串化表示”,JS中处理JSON的核心就是将JSON字符串转换为JS对象(解析)和将JS对象转换为JSON字符串(序列化)。
JSON解析:将JSON字符串转换为JS对象
当从后端API获取数据或读取本地JSON文件时,数据通常以字符串形式传输,此时需通过解析将其转换为JS对象,才能访问属性和方法,JavaScript提供了两种原生解析方式:JSON.parse()和eval()(不推荐)。
JSON.parse():标准解析方法
JSON.parse()是ES5引入的官方方法,用于将符合JSON格式的字符串转换为JS对象,其基本语法为:
const JSObject = JSON.parse(jsonString[, reviver]);
jsonString:必填,需符合JSON格式的字符串。reviver:可选,转换函数,可在解析过程中对值进行修改,函数接收key和value参数,返回处理后的值。
基础示例
const jsonString = '{"name":"Alice","age":25,"hobbies":["reading","coding"],"isStudent":true}';
const obj = JSON.parse(jsonString);
console.log(obj.name); // "Alice"
console.log(obj.hobbies[0]); // "reading"
console.log(obj.isStudent); // true
解析嵌套JSON
const nestedJson = '{"user":{"id":1,"profile":{"city":"Beijing"}}}';
const parsed = JSON.parse(nestedJson);
console.log(parsed.user.profile.city); // "Beijing"
使用reviver函数处理日期
JSON本身不支持日期对象,若需将JSON中的日期字符串转换为Date对象,可通过reviver实现:
const jsonWithDate = '{"createdAt":"2023-10-01T12:00:00Z"}';
const data = JSON.parse(jsonWithDate, (key, value) => {
if (key === "createdAt") {
return new Date(value); // 将日期字符串转为Date对象
}
return value;
});
console.log(data.createdAt instanceof Date); // true
console.log(data.createdAt.toISOString()); // "2023-10-01T12:00:00.000Z"
常见错误:JSON格式不符合规范
若传入的字符串不符合JSON格式(如键用单引号、包含undefined等),JSON.parse()会抛出SyntaxError:
const invalidJson = "{'name':'Bob'}"; // 键用单引号,报错
// const obj = JSON.parse(invalidJson); // SyntaxError: Unexpected token ' in JSON
解决方案:确保字符串严格遵循JSON格式,或使用try-catch捕获错误:
function safeParse(jsonStr) {
try {
return JSON.parse(jsonStr);
} catch (error) {
console.error("JSON解析失败:", error);
return null;
}
}
eval():不推荐使用
虽然eval()可以解析JSON字符串(甚至非严格JSON格式),但存在严重安全隐患:它会执行字符串中的任意JS代码,若数据来自不可信来源(如用户输入),可能导致代码注入攻击。
const maliciousJson = '{"name":"Eve","maliciousCode":"alert(黑客代码)"}';
// 危险!eval会执行maliciousCode
const obj = eval(`(${maliciousJson})`); // 即使加括号,仍不安全
永远不要用eval()解析JSON,优先使用JSON.parse()。
JSON序列化:将JS对象转换为JSON字符串
当前端需将数据发送给后端(如AJAX请求)或存储到本地(如localStorage)时,需将JS对象序列化为JSON字符串,JavaScript提供了JSON.stringify()方法,同时支持格式化、过滤等高级功能。
JSON.stringify():基础序列化
其基本语法为:
const jsonString = JSON.stringify(JSObject[, replacer[, space]]);
JSObject:必填,需序列化的JS对象。replacer:可选,可为数组或函数,用于控制哪些属性被序列化。space:可选,格式化输出,值为数字(缩空格数,最大10)或字符串(缩进字符串)。
基础示例
const obj = {
name: "Charlie",
age: 30,
hobbies: ["swimming", "travel"],
isStudent: false,
};
const jsonString = JSON.stringify(obj);
console.log(jsonString);
// '{"name":"Charlie","age":30,"hobbies":["swimming","travel"],"isStudent":false}'
序列化特殊类型
JSON.stringify()对特殊类型的处理规则如下:
undefined、函数、Symbol:会被忽略(不在序列化结果中);Date对象:自动调用toISOString()转为日期字符串;NaN、Infinity:转为null;- 循环引用的对象:抛出
TypeError(对象中存在循环引用时,如obj.self = obj)。
const specialObj = {
name: "David",
date: new Date(),
fn: function() {}, // 函数被忽略
undef: undefined, // undefined被忽略
circular: {}, // 循环引用
};
specialObj.circular = specialObj; // 循环引用
console.log(JSON.stringify(specialObj));
// '{"name":"David","date":"2023-10-01T12:00:00.000Z"}' // 函数、undefined被忽略
// JSON.stringify(specialObj); // TypeError: Cyclical object value
replacer:过滤或修改序列化结果
数组形式:指定序列化的属性
const user = {
id: 101,
password: "123456", // 不想序列化密码
profile: {
nickname: "Dave",
age: 28,
},
};
// 只序列化id和profile中的nickname
const filteredJson = JSON.stringify(user, ["id", "profile", "nickname"]);
console.log(filteredJson);
// '{"id":101,"profile":{"nickname":"Dave"}}' // password和age被过滤
函数形式:动态处理属性值
const product = {
name: "Laptop",
price: 999.99,
stock: 10,
discount: 0.2,
};
const processedJson = JSON.stringify(product, (key, value) => {
if (key === "price") {
return value * (1 - product.discount); // 计算折扣价
}
if (key === "stock" && value === 0) {
return "缺货"; // 库存为0时返回字符串
}
return value;
});
console.log(processedJson);
// '{"name":"Laptop","price":799.992,"stock":10,"discount":0.2}'
space:格式化输出
space参数可使JSON字符串更易读,适合调试或日志记录:
const data = {
user: { name: "Eve", role: "admin" },
actions: ["login", "delete", "edit"],
};
// 使用2个空格缩进
const prettyJson = JSON.stringify(data, null, 2);
console.log(prettyJson);
/*
{
"user": {
"name": "Eve",
"role": "admin"
},
"actions": [
"login",
"delete",
"edit"
]
}
*/
// 使用制表符缩进
const tabJson = JSON.stringify(data,


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