JSON 基础
JSON 的语法规则、数据类型和常用方法
问题
什么是 JSON?它的语法规则是什么?如何在 JavaScript 中使用?
解答
什么是 JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。
语法规则
{
"name": "张三",
"age": 25,
"isStudent": false,
"hobbies": ["读书", "游泳"],
"address": {
"city": "北京",
"street": "朝阳路"
},
"spouse": null
}
JSON 支持的数据类型:
- 字符串:必须用双引号
- 数字:整数或浮点数
- 布尔值:
true或false - null:空值
- 数组:有序列表
- 对象:键值对集合
JavaScript 中的 JSON 方法
// JSON.stringify() - 将对象转为 JSON 字符串
const obj = {
name: '张三',
age: 25,
hobbies: ['读书', '游泳']
};
const jsonStr = JSON.stringify(obj);
console.log(jsonStr);
// {"name":"张三","age":25,"hobbies":["读书","游泳"]}
// 格式化输出,缩进 2 个空格
const prettyJson = JSON.stringify(obj, null, 2);
console.log(prettyJson);
// 使用 replacer 过滤属性
const filtered = JSON.stringify(obj, ['name', 'age']);
console.log(filtered); // {"name":"张三","age":25}
// JSON.parse() - 将 JSON 字符串转为对象
const parsed = JSON.parse(jsonStr);
console.log(parsed.name); // 张三
// 使用 reviver 转换值
const jsonWithDate = '{"date":"2024-01-01T00:00:00.000Z"}';
const objWithDate = JSON.parse(jsonWithDate, (key, value) => {
if (key === 'date') return new Date(value);
return value;
});
console.log(objWithDate.date instanceof Date); // true
注意事项
// 1. JSON 键名必须是双引号字符串
// 正确:{"name": "张三"}
// 错误:{name: "张三"} 或 {'name': '张三'}
// 2. 不支持的类型会被忽略或转为 null
const special = {
fn: function() {}, // 函数 - 被忽略
undef: undefined, // undefined - 被忽略
sym: Symbol('id'), // Symbol - 被忽略
date: new Date(), // Date - 转为字符串
regex: /abc/, // RegExp - 转为空对象 {}
nan: NaN, // NaN - 转为 null
infinity: Infinity // Infinity - 转为 null
};
console.log(JSON.stringify(special));
// {"date":"2024-...","regex":{},"nan":null,"infinity":null}
// 3. 循环引用会报错
const circular = { name: '张三' };
circular.self = circular;
// JSON.stringify(circular); // TypeError: Converting circular structure to JSON
// 4. toJSON 方法可自定义序列化
const user = {
name: '张三',
password: '123456',
toJSON() {
return { name: this.name }; // 隐藏密码
}
};
console.log(JSON.stringify(user)); // {"name":"张三"}
深拷贝的局限性
// JSON 方式实现深拷贝
const original = {
name: '张三',
info: { age: 25 }
};
const cloned = JSON.parse(JSON.stringify(original));
cloned.info.age = 30;
console.log(original.info.age); // 25 - 原对象不受影响
// 但无法处理特殊类型
const withSpecial = {
date: new Date(),
fn: () => {},
undef: undefined
};
const clonedSpecial = JSON.parse(JSON.stringify(withSpecial));
console.log(clonedSpecial);
// { date: "2024-..." } - date 变成字符串,fn 和 undef 丢失
关键点
- JSON 键名必须用双引号,值的字符串也必须用双引号
JSON.stringify()会忽略函数、undefined、SymbolJSON.parse()的 reviver 参数可用于转换特殊类型(如日期)- JSON 深拷贝无法处理循环引用、函数、Date、RegExp 等类型
- 对象可通过
toJSON()方法自定义序列化行为
目录