# 深浅拷贝

深拷贝:Deep copy;浅拷贝:Shallow copy。

# 浅拷贝

创建一个新的对象,来接受重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象;但如果属性是引用数据类型,复制的就是内存中的地址

也就是说,如果一个对象改变了这个内存中的地址,一定会影响到另一个对象。下面是几种实现浅拷贝的方法。

# Object.assign

Object.assign(target, ...sources)

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the target object.

需要注意,①它不会拷贝对象的继承属性;②不会拷贝对象的不可枚举属性;③可以拷贝 Symbol 类型的属性;④target object 会被改变,source objects 不会被改变。










 






let t = {}
let s = { a: { b: 1 }, unique: Symbol('u') }
Object.defineProperty(s, 'innumerableKey', {
  value: '不可枚举属性值',
  enumerable: false
})

Object.assign(t, s)

console.log('t', t)

s.a.b = 2

console.log('t', t)
console.log('s', s)

这里有意思的是高亮的这一行,打印出来 target object 的值中 s.a.b 已经是 2 了,由此也能看出一段 JavaScript 代码在执行之前需要被 JavaScript 引擎编译,编译完成之后,才会进入执行阶段。大致流程可以参考:

source object 改变了深层次的属性值时,target object 也会跟随变化,说明其中存在着访问共同堆内存的问题

# 扩展运算符

扩展运算符(...):Spread syntax。/spred/

let obj = { a: 1, b: { c: 2 } }
let obj2 = { ...obj }

obj.b.c = 2

console.log(obj2)

可以看出,扩展运算符和 Object.assign 一样,对于深层级对象同样是复制内存地址。两者的区别在于,并没有那个是 target object,如果不给属性重新赋值,原始对象不会发生改变。