一、前言

在咱们面试过程中,面试官经常会提及到深浅复制的问题。想必大多数小伙伴会说到JSON.parse(JSON.stringify(obj))。正好今日我就和咱们好好唠一唠这个JSON.stringify

二、概念

JSON.stringify关于咱们不生疏,一般用来处理序列化(深复制)。便是把咱们的目标转化JSON字符串,此办法确实很方便在咱们的工作中,可是,这个办法也会有一些坏处,仅仅咱们不怎么遇到。

let obj = {
    name: 'iyongbao'
}
console.log(JSON.stringify(obj)); // {"name":"iyongbao"}

三、坏处

1. 对函数不友好

如果咱们的目标特点是一个函数,那么在序列化的时候该特点丢掉

let obj = {
    name: 'iyongbao',
    foo: function () {
        console.log(`${ this.name }是一个小菜鸟!`)
    }
}
console.log(JSON.stringify(obj)); // {"name":"iyongbao"}

2. 对undefined不友好

如果目标的特点值是undefined,转化后会丢掉

let obj = {
    name: undefined
}
console.log(JSON.stringify(obj)); // {}

3. 对正则表达式不友好

如果目标的特点是一个正则表达式,转化后就会变成一个空的Object

let obj = {
    name: 'iyongbao',
    zoo: /^i/ig,
    foo: function () {
        console.log(`${ this.name }是一个小菜鸟!`)
    }
}
console.log(JSON.stringify(obj)); // {"name":"iyongbao","zoo":{}}

4. 数组目标

如果是一个数组目标,以上的情况也会发生。

let arr = [
    {
        name: undefined
    }
]
console.log(JSON.stringify(arr)); // [{}]

四、JSON.stringify拓展

说完了JSON.stringify缺乏,下面咱们来说一下你可能没有触摸过的其他特性,期望看完会对你有所协助。

1. 接收一个数组(过滤)

其实JSON.stringify第二参数,可能咱们不经常用到。咱们能够传入一个数组,值便是对应咱们目标key,我称之为过滤。

let obj = {
    name: 'iyongbao',
    age: 25,
    hobby: ['JavaScript', 'Vue']
}
let res = JSON.stringify(obj, ['name']);
console.log(res); // {"name":"iyongbao"}

2. 接收一个函数

第二个参数也可所以一个函数,也是类似过滤作用

let obj = {
    name: 'iyongbao',
    age: 25,
    hobby: ['JavaScript', 'Vue']
}
let res = JSON.stringify(obj, (key, value) => {
    if (key === 'age') return undefined;
    return value;
});
console.log(res); // {"name":"iyongbao","hobby":["JavaScript","Vue"]}

3. 缩进

第三个参数能够接收一个数字,表明缩进多少字符

let obj = {
    name: 'iyongbao',
    age: 25,
    hobby: ['JavaScript', 'Vue']
}
let res = JSON.stringify(obj, null, 2);
console.log(res);

你不知道的JSON.stringify神操

4. 自身toJSON办法

目标能够有一个自身的toJSON特点,是一个返回值办法,用来输出咱们自定义的数据样式。

let obj = {
    name: 'iyongbao',
    age: 25,
    toJSON: function () {
        return {
            message: `${ this.name }的年纪为${ this.age }`
        }
    }
}
let res = JSON.stringify(obj);
console.log(res); // {"message":"iyongbao的年纪为25"}

五、总结

好了,今日就和咱们共享到这吧。一般如果然涉及到深复制,我还是首选自己封装一个办法或者是使用第三方插件库来做深复制,这样最稳妥,避免不必要的麻烦。