我对 javascript 对象(数组)深复制有问题。我读了很多处理它的好方法。而且我也知道 jQuery 有 $.extend API 来解决这个问题。但我的问题是:我可以只使用 JSON stringify 和 parse 方法来解决这个问题吗?
这是我的代码:
function deepCopy(oldValue) {
var newValue
strValue = JSON.stringify(oldValue)
return newValue = JSON.parse(strValue)
}
var a = {
b: 'b',
c: [1,2,4],
d: null
}
copy = deepCopy(a)
console.log(a === copy) // false
console.log(a.c === copy.c) // false
PS:我知道如果不是所有对象都是可序列化的,但我知道的唯一情况是当对象包含一个函数属性时。还有其他情况吗?
如果您的对象“小”并且只包含可序列化的属性,则使用 JSON 序列化的简单 deepCopy hack 应该没问题。但是,如果您的对象很大,您可能会遇到问题。如果它包含不可序列化的属性,这些属性将会丢失:
var o = {
a: 1,
b: 2,
sum: function() { return a + b; }
};
var o2 = JSON.parse(JSON.stringify(o));
console.log(o2);
产量:
Object {a: 1, b: 2}
有趣的是,C# 中的相当多的深度复制解决方案都是类似的序列化/反序列化技巧。
附录:不确定您希望在比较复制后的对象方面得到什么。但是,对于复杂的对象,您通常需要编写自己的
Compare()
和/或 Equals()
方法才能进行准确比较。
还值得注意的是,这种副本不保留类型信息。
JSON.parse(JSON.stringify(new A())) instanceof A === false
你可以这样做,但由于上面列出的一些原因,这是有问题的:
我质疑性能。
你有任何不可序列化的属性吗?
最大的问题是:您的克隆缺少类型信息。根据您正在做的事情,这可能很重要。实现者是否向原始对象的原型添加了方法?那些都消失了。我不确定你还会失去什么。
我认为您正在寻找的是这样的: 如果您有一个真正嵌套的对象结构,那么要进行深层复制,您可以使用 JSON.stringify()。
请看下面的例子:
var obj= {
'a':1,
'b':2,
'c': {
'd':{
'e' : 3
}
}
}
var newObj = {...obj};
var lastObj = JSON.parse(JSON.stringify(obj));
obj.c.d.e =19;
console.log('obj '+obj.c.d.e);
console.log('newObj '+obj.c.d.e);
console.log('lastObj'+lastObj.c.d.e);
现在,lastObj 真正与 obj 分离,而如果您使用 ...(spread) 运算符,它也无法在真正复杂的对象中工作。
希望这有帮助!
现在,您可以在现代节点和浏览器环境中使用本机深度克隆:
const value = {
a: 'a',
b: 'b',
foo: {
"bar": 42
}
}
const copy = structuredClone(value)
这个类似问题的answer提供了更多选择。