JSON.parse(JSON.stringify(obj))
是一种常见的实现深拷贝的方法。它将对象转换为 JSON 字符串,然后再解析这个字符串,从而创建了一个新的对象。这个过程会创建一个完全独立的对象,实现了深拷贝。 但是
在某些情况下可以实现对象的深拷贝,但是也存在一些特殊情况和限制:
1.可以使用它来做深拷贝的情况:
- 对象是纯粹的JSON数据结构,即它只包含简单的数据类型(如字符串,数字,布尔值,数组,对象),并且没有包含函数,正则表达式,日期对象等特殊的类型时候可以使用。 例如:
js
const obj={
name:'Marcos',
age:12,
obj2:{
name:'Marcos2',
age:12,
obj3:{
name:'Marcos3',
age:12
}
},
arr2:[1,2,3,4,5]
}
const objCopy =JSON.parse(JSON.stringify(obj))
console.log(objCopy)
2.对象中不包含循环引用,即对象的属性之间没有互相引用导致循环结构。如果是循环结构会导致JSON.stringify报错。 例如:
js
const obj={
name:'Marcos2',
age:12,
}
obj.obj2=obj
const objCopy =JSON.parse(JSON.stringify(obj))
console.log(objCopy)
2.特殊情况:
1.对象中包含 undefined、Symbol、function 类型的属性时,在转换为 JSON 字符串时会被忽略丢失。
js
let obj = {
age: 18,
fn: function () {
console.log('fn');
},
bb: undefined
};
const objCopy = JSON.parse(JSON.stringify(obj))
console.log('obj', obj);
console.log('objCopy', objCopy);
2.对象中包含 Date 类型的属性时,转换为 JSON 字符串后会变成字符串形式,而不再是 Date 对象。
js
let obj = {
age: 18,
date:new Date()
};
const objCopy = JSON.parse(JSON.stringify(obj))
console.log('obj', obj);
console.log('objCopy', objCopy);
3.对象中包含 RegExp 类型的属性时,转换为 JSON 字符串后会变成空对象 {}
。
js
let obj = {
age: 18,
reg:new RegExp('^[a-zA-Z0-9_-]{6,16}$'),
error:new Error('用户名不能为空')
};
const objCopy = JSON.parse(JSON.stringify(obj))
console.log('obj', obj);
console.log('objCopy', objCopy);
综上所述,JSON.parse(JSON.stringify(obj))
可以实现简单的 JSON 数据结构的深拷贝,但在处理包含特殊类型或循环引用的对象时,可能会出现问题,在实际开发中还需要结合实际情况使用。
拓展运算符和 JSON.parse(JSON.stringify(obj))对比区别
扩展运算符(spread operator)...
属于浅拷贝。它可以用于创建一个新的对象或数组,并将原始对象或数组的属性或元素复制到新对象或数组中。对于对象来说,使用扩展运算符只会复制对象的第一层属性,而嵌套对象仍然是引用关系,因此并不是完全独立的拷贝。
区别在于深拷贝会递归地复制所有层级的对象,使得原对象和拷贝后的对象完全独立,而浅拷贝只会复制对象的第一层属性,嵌套对象仍然是引用关系。因此,深拷贝会更加彻底地复制整个对象结构,而浅拷贝只会复制对象的最外层属性。