【JavaScript】JSON

JSON 简介

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,并且容易被多种编程语言解析和生成。

编写 demo.json 文件:

{
    "name": "John",
    "age": 30,
    "isMarried": false,
    "hobbies": ["reading", "hiking", "photography"],
    "address": {
        "city": "New York",
        "country": "USA"
    }
}



JSON 方法

在 JS 中,可以使用 JSON.parse() 将 JSON 字符串转换为 JS 对象,使用 JSON.stringify() 将 JS 对象转换为 JSON 字符串。

parse 是 “解析” 的意思;stringify 是 “字符串化” 的意思。

const obj = {
    name: 'superman',
    age: 21,
    isMarried: false,
    hobbies: ['basketball'],
    brother: { name: 'monster' },
    children: null,
};

const jsonStr = JSON.stringify(obj);
console.log(jsonStr);

const newObject = JSON.parse(jsonStr);
console.log(newObject);



JSON.stringify 的使用

特殊的第一参数

  1. 直接忽略的情况:
const age = Symbol('age');

const person = {
    _function: function () {}, // 函数 → 直接忽略
    _undefined: undefined, // undefined → 直接忽略
    [age]: 30, // symbol → 直接忽略
};

// 不可枚举属性 → 直接忽略
Object.defineProperty(person, 'car', {
    value: 'BMW',
    enumerable: false,
});

// 继承属性 → 直接忽略
const obj = { living: true };
Object.setPrototypeOf(person, obj);

console.log(JSON.stringify(person)); // {}
  1. 处理为 null 的情况:
const obj = {
    _null: null, // null → 返回 null
    _NaN: NaN, // NaN → 返回 null
    _Infinity1: Infinity, // Infinity → 返回 null
    _Infinity2: -Infinity, // -Infinity → 返回 null
};
console.log(JSON.stringify(obj)); // {"_null":null, "_NaN":null, "_Infinity1":null, "_Infinity2":null}
  1. 其他情况:
const obj = {
    _RegExp: new RegExp(), // 正则 → 返回空对象 {}
    _Date: new Date(), // Date → 以字符串形式返回
};
console.log(JSON.stringify(obj)); // {"_RegExp":{}, "_Date":"2023-08-01T03:10:18.011Z"}

在数组中遇到 undefined、function 和 symbol 时会返回 null(以保证单元位置不变)。

JSON.stringify([1, undefined, function () {}, 4]); // "[1, null, null,4]"
JSON.stringify({ a: 2, b: function () {} }); // "{"a":2}"

对包含循环引用的对象执行 JSON.stringify(..) 会出错。


第二参数

JSON.stringify 可传入 array 作为第 2 参数,表示获取指定属性:

const obj = {
    name: 'superman',
    age: 21,
    gender: 'male',
    address: 'China',
};
console.log(JSON.stringify(obj, ['name', 'gender'])); // {"name":"superman", "gender":"male"}

JSON.stringify 可传入 callback 作为第 2 参数,以获取函数处理后的数据:

const a = {
    b: 42,
    c: '42',
    d: [1, 2, 3],
};

JSON.stringify(a, ['b', 'c']); // '{"b":42, "c":"42"}'

JSON.stringify(a, function (k, v) {
    if (k !== 'c') return v;
}); // '{"b":42, "d":[1,2,3]}'

callback 的参数 k 在第一次调用时为 undefined(就是对对象本身调用的那次)。由于字符串化是递归的,因此数组 [1,2,3] 中的每个元素都会通过参数 v 传递给 callback,即 123,参数 k 是它们的索引值,即 012


第三参数

JSON.stringify 可传入 space 作为第 3 参数,用于美化格式。space 为正整数时是指定每一级缩进的字符数,它还可以是字符串,此时最前面的十个字符被用于每一级的缩进:

const a = {
    b: 42,
    c: '42',
    d: [1, 2, 3],
};

JSON.stringify(a, null, 3);
// "{
//    "b": 42,
//    "c": "42",
//    "d": [
//       1,
//       2,
//       3
//    ]
// }"

JSON.stringify(a, null, '-----');
// "{
// -----"b": 42,
// -----"c": "42",
// -----"d": [
// ----------1,
// ----------2,
// ----------3
// -----]
// }"

自定义 stringify

如果对象中定义了 toJSON(),JSON 字符串化时会首先调用该方法,然后用它的返回值来进行序列化。

const a = { b: 42, c: '42' };

// 自定义的 JSON 序列化
a.toJSON = function () {
    // 序列化仅包含 b
    return { b: this.b };
};

JSON.stringify(a); // '{"b":42}'
const obj = {
    name: 'superman',
    hobbies: ['basketball', 'football'],
    age: 21,
    toJSON() {
        return `${this.name}, ${this.hobbies}, ${this.age}`;
    },
};
console.log(JSON.stringify(obj)); // "superman, basketball,football, 21"

使用场景

  1. 配合 localStorage 使用:
const obj = { name: 'superman' };
localStorage.setItem('obj', JSON.stringify(obj));
const objStr = localStorage.getItem('obj');
  1. 深拷贝比较简单的对象:
const obj = {
    name: 'superman',
    hobbies: ['basketball', 'football'],
    age: 21,
};
const objDeepCopy = JSON.parse(JSON.stringify(obj));
objDeepCopy.hobbies[0] = 'swimming';
console.log(obj); // {name:'superman', hobbies:['basketball','football'], age:21}
console.log(objDeepCopy); // {name:'superman', hobbies:['swimming','football'], age:21}
  1. 删除对象的指定属性:
const obj = {
    name: 'superman',
    hobbies: ['basketball', 'football'],
    age: 21,
};

const deleteProperty = (obj, prop) => {
    const jsonStr = JSON.stringify(obj, (key, value) => {
        if (key === prop) {
            return undefined; // stringify 会忽略值为 undefined 的属性
        }
        return value;
    });
    return JSON.parse(jsonStr);
};

const newObj = deleteProperty(obj, 'hobbies');
console.log(newObj); // { name:'superman', age:21 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JS.Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值