Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.assign(target, ...sources) 【target:目标对象】,【souce:源对象(可多个)】
1.如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。
2.Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
Object.assign()拷贝
当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。
如下,如果当源对象只有一层,并且value为值类型,当用Object.assign()拷贝的时候是深拷贝,拷贝以后,修改源对象的值,目标对象并不会改变,为深拷贝
let a = { b: 1, c: 2 }let result = Object.assign({},a)a.b = 3console.log(result.b) // 打印 1
如果当源对象的value有对象的时候,拷贝以后,修改源对象里面对象的值,目标对象会改变,为浅拷贝
let a = { b: { d: 1, f: 3 }, c: 2 }let result = Object.assign({},a)a.b.d = 33console.log(result.b.d) // 打印 33
Object.assign的拷贝,是对于第一层属性的拷贝。
如下,源对象的value是一个对象,但是我修改的是源对象第一层的的值,并不会对result值产生影响。说明Object.assign的拷贝,只是针对于第一层属性的拷贝。
let a = { b: { d: 1, f: 3 }, c: 2 }let result = Object.assign({},a)a.b = []console.log(result.b.d) // 打印 1
最后写在,深拷贝的写法也有N种,我经常用到的是JSON.parse(JSON.stringify(obj)),或者是使用lodash的深拷贝就得了。