一、前言
在我们
面试过程中
,面试官经常会提及到深浅拷贝
的问题。想必大多数小伙伴会说到JSON.parse(JSON.stringify(obj))
。正好今天我就和大家好好唠一唠这个JSON.stringify
。
二、概念
JSON.stringify
对于我们不陌生,一般用来处理序列化
(深拷贝)。就是把我们的对象
转换 为JSON字符串
,此方法确实很方便在我们的工作中,但是
,这个方法也会有一些弊端,只是我们不怎么遇到。
js
let obj = {
name: 'iyongbao'
}
console.log(JSON.stringify(obj)); // {"name":"iyongbao"}
三、弊端
1. 对函数不友好
如果我们的对象属性
是一个函数
,那么在序列化
的时候该属性
会丢失
。
js
let obj = {
name: 'iyongbao',
foo: function () {
console.log(`${ this.name }是一个小菜鸟!`)
}
}
console.log(JSON.stringify(obj)); // {"name":"iyongbao"}
2. 对undefined不友好
如果对象的属性
值是undefined
,转换后会丢失
。
js
let obj = {
name: undefined
}
console.log(JSON.stringify(obj)); // {}
3. 对正则表达式不友好
如果对象的属性
是一个正则表达式
,转换后就会变成一个空的Object
js
let obj = {
name: 'iyongbao',
zoo: /^i/ig,
foo: function () {
console.log(`${ this.name }是一个小菜鸟!`)
}
}
console.log(JSON.stringify(obj)); // {"name":"iyongbao","zoo":{}}
4. 数组对象
如果是一个数组对象
,以上的情况也会发生。
js
let arr = [
{
name: undefined
}
]
console.log(JSON.stringify(arr)); // [{}]
四、JSON.stringify拓展
说完了
JSON.stringify
的不足
,下面我们来说一下你可能没有接触过的其他特性
,希望看完会对你有所帮助。
1. 接收一个数组(过滤)
其实JSON.stringify
有第二
个参数
,可能我们不经常用到。我们可以传入
一个数组
,值就是对应我们对象
的key
,我称之为过滤。
js
let obj = {
name: 'iyongbao',
age: 25,
hobby: ['JavaScript', 'Vue']
}
let res = JSON.stringify(obj, ['name']);
console.log(res); // {"name":"iyongbao"}
2. 接收一个函数
第二个参数
也可以是一个函数
,也是类似过滤
的效果
。
js
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. 缩进
第三个参数
可以接收一个数字
,表示缩进
多少字符
。
js
let obj = {
name: 'iyongbao',
age: 25,
hobby: ['JavaScript', 'Vue']
}
let res = JSON.stringify(obj, null, 2);
console.log(res);
4. 自身toJSON方法
对象可以有一个自身的toJSON
属性,是一个
有返回值
的方法
,用来输出我们自定义的数据样式。
js
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"}
五、总结
好了,今天就和大家分享到这吧。一般如果真涉及到深拷贝
,我还是首选自己封装
一个方法
或者是使用第三方
的插件库
来做深拷贝,这样最保险,避免不必要的麻烦。