在下面的代码中实现对象中的卷影复制,但差异输出让我困惑;
Object.assign:
var obj = {
name: 'wsscat',
age: 0,
add: {
a: 'beijing'
}
}
var obj2 = Object.assign({}, obj);
obj2.age = 18;
obj2.add.a = 'shanghai';
console.log(obj)
console.log(obj2)
输出:
{ name: 'wsscat', age: 0, add: { a: 'shanghai' } }
{ name: 'wsscat', age: 18, add: { a: 'shanghai' } }
使用 ="分配" 来实现浅拷贝:
var obj = {
name: 'wsscat',
age: 0,
add: {
a: 'beijing'
}
}
// var obj2 = Object.assign({}, obj);
var obj2 = obj;
obj2.age = 18;
obj2.add.a = 'shanghai';
console.log(obj)
console.log(obj2)
输出:
{ name: 'wsscat', age: 18, add: { a: 'shanghai' } }
{ name: 'wsscat', age: 18, add: { a: 'shanghai' } }
答案 0 :(得分:3)
我认为你的意思是“浅拷贝”,而不是“影子拷贝”,所以我会在答案中提到前者。
通过使用赋值运算符=
,您只需复制引用,因此obj2
指向与obj
相同的对象,因此更改属性会反映在两者上。
使用Object.assign
的方式,通过将所有属性从源对象obj
复制到目标对象(空)来创建浅层克隆,然后将其分配给变量obj2
。
原始数据类型(null,undefined,String,Number,Boolean)按值复制,因此两个对象上的键name
和age
在内存中包含不同的值)。对象类型(Object,Arrray,Function)通过引用复制,因此add
属性下的对象在obj
和obj2
之间共享。 obj2.add.a
中的任何更改都会反映在obj.add.a
。
查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assigne/
的polyfill实现编辑:与polyfill实施的另一个链接:https://gist.github.com/spiralx/68cf40d7010d829340cb
EDIT2:澄清复制基元类型和对象之间的区别。