Z
ZHANK

JSON 处理

掌握 JSON.stringify/parse、深拷贝

JSON 处理

JSON(JavaScript Object Notation)是最流行的数据交换格式。

学完本章你将: 掌握 JSON.stringify/parse、序列化选项。


JSON.stringify —— 对象转字符串

javascript
let user = {
    name: "Alice",
    age: 25,
    isAdmin: false,
    skills: ["JS", "Python"],
};

let json = JSON.stringify(user);
console.log(json);
// {"name":"Alice","age":25,"isAdmin":false,"skills":["JS","Python"]}

// 美化输出
console.log(JSON.stringify(user, null, 2));
/*
{
  "name": "Alice",
  "age": 25,
  "isAdmin": false,
  "skills": [
    "JS",
    "Python"
  ]
}
*/

// 选择性序列化(replacer 函数)
let safe = JSON.stringify(user, (key, value) => {
    if (key === "password") return undefined; // 排除敏感字段
    return value;
});

JSON.parse —— 字符串转对象

javascript
let jsonStr = '{"name":"Alice","age":25}';
let obj = JSON.parse(jsonStr);
console.log(obj.name); // "Alice"

// reviver 函数处理
let dateStr = '{"event":"meeting","date":"2024-06-15T10:00:00Z"}';
let parsed = JSON.parse(dateStr, (key, value) => {
    if (key === "date") return new Date(value);
    return value;
});
console.log(parsed.date instanceof Date); // true

JSON 不能处理的类型

javascript
let special = {
    fn: function() {},     // → 丢失
    undef: undefined,      // → 丢失
    sym: Symbol("id"),     // → 丢失
    big: 1n,               // → TypeError
    date: new Date(),      // → 变成字符串
    map: new Map(),        // → 变成 {}
};

// JSON.stringify(special); // ❌ TypeError: BigInt

// 自定义 toJSON
let custom = {
    name: "Alice",
    createdAt: new Date(),
    toJSON() {
        return { name: this.name };
    },
};
console.log(JSON.stringify(custom)); // {"name":"Alice"}

深拷贝

javascript
let original = { a: 1, b: { c: 2 } };

// JSON 方式(有限制)
let clone = JSON.parse(JSON.stringify(original));
clone.b.c = 99;
console.log(original.b.c); // 2(深拷贝成功)

// 限制:不能拷贝函数、undefined、Symbol、循环引用

// structuredClone(现代推荐)
let modern = structuredClone(original);
modern.b.c = 99;
console.log(original.b.c); // 2