Object.assign() 和'=assign' 之间有什么区别来实现数组或对象中的浅拷贝?

duk*_*god 1 javascript

在下面的代码中实现对象中的浅拷贝,但不同的输出让我感到困惑:

对象.赋值:

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)
Run Code Online (Sandbox Code Playgroud)

输出:

{ name: 'wsscat', age: 0, add: { a: 'shanghai' } }
{ name: 'wsscat', age: 18, add: { a: 'shanghai' } }
Run Code Online (Sandbox Code Playgroud)

while use = "assign"实现浅拷贝:

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)
Run Code Online (Sandbox Code Playgroud)

输出:

{ name: 'wsscat', age: 18, add: { a: 'shanghai' } }
{ name: 'wsscat', age: 18, add: { a: 'shanghai' } } 
Run Code Online (Sandbox Code Playgroud)

And*_*myk 5

我想你的意思是“浅拷贝”,而不是“影子拷贝”,所以我会在我的回答中提到前者。

通过使用赋值运算符,=您只需复制引用,因此obj2指向与 相同的对象obj,因此更改的属性会反映在两者上。

您使用的方式是Object.assign通过将所有自己的属性从源对象复制obj到目标对象(空),然后将其分配给变量来创建浅克隆obj2

原始数据类型(null、undefined、String、Number、Boolean)按值复制,因此两个对象上的键nameage在内存中包含不同的值。对象类型(对象、数组、函数)是通过引用复制的,因此属性下的对象在和add之间共享。中的任何更改都将反映在 上。objobj2obj2.add.aobj.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:阐明了复制原始类型和对象之间的区别。