语法:
Object.assign(targetObj, copyObj_1, ....,copyObj_n );
参数解释:
①:targetObj ==>> 目标对象,即将参数copyObj_1, ....,copyObj_n的自有属性拷贝至的目标对象。最后返回的也是这个目标对象。
②:copyObj_1 、copyObj_2、... 、copyObj_n ==>> 被拷贝对象,可以是一个对象,也可以是N个这样的被拷贝对象。
功能:
将被拷贝对象的自有属性(非来自于被拷贝对象原型链上的属性) 浅拷贝至目标对象中。
●● Object.assign()浅拷贝说明:(关于这点,我会在后边的特别补充说明中说具体说明)
对于多层属性嵌套,也就是属性的值指向一个对象时候,Object.assign()拷贝的是其属性值所指向的对象的内存地址,也就是说当源对象中的该属性值发生变化时,拷贝后的目标对象中的值也会发生变化。
特别补充说明:
●●● 被拷贝对象中具有相同的属性,后边的属性会覆盖前面的属性。
比如:Object.assign({}, obj_1, obj_2);
obj_1和obj_2中有相同的属性,后边obj_2的属性会覆盖前面obj_1中的相同属性
●●● 自有属性与来自原型链上的属性
自有属性:即该对象自己的属性,非来自于其原型链上继承而来的属性。
下边看个例子就明白了
const origin = {
age: 11, // ---> 原型上的属性
id: 12 // ---> 原型上的属性
};
let obj = Object.create(origin);
obj.name= "lle"; // ---> 自有属性
上边这段代码,对于obj来讲,origin就是其原型。obj会继承其原型上的属性, 而后边的name才是它自有的属性。
Object.assign()不会拷贝来自原型的属性,我们接着看下边的例子
结果和我们预期的一样,Object.assign()并没有拷贝obj来自原型链上的属性const origin = {
age: 11,
id: 12
};
let obj = Object.create(origin);
obj.name= "lle";
let copiedObj = Object.assign({}, obj);
console.log("=========>>>", copiedObj);
那么问题来了,如果我需要拷贝被拷贝对象中的原型属性呢?
答案很简单,我们单独获取被拷贝对象原型链上的属性然后放进目标对象里就可以了!
const origin = {
age: 11,
id: 12
};
let obj = Object.create(origin);
obj.name= "lle";
let prototypeProperty = Object.getPrototypeOf(obj); // ---> 单独获取出obj上来自原型上的属性
let copiedObj = Object.assign({}, prototypeProperty, obj);
console.log("=========>>>", copiedObj);
我们再来看看结果
和预想的一样,目标对象也有了来自obj原型上的属性●●● 浅拷贝的问题
在上边开篇中的功能中我就说了Object.assign()是浅拷贝,关于文字上的描述我这里就不赘述了,可以参考上边的功能说明。
下边我们直接上例子
结果和开篇里功能中的描述一致,单层属性未发生改变,深层,也就是属性值为一个新对象的时候拷贝出来的新对象跟着源对象的变化而变化了!let obj = {
name: "lle",
age: 11,
info: {
class: 1
}
};
let copiedObj = Object.assign({}, obj);
console.log("=========>>>", copiedObj);
setTimeout(() => {
obj.name= "wang";
obj.info.class= 2;
console.log("=========>>>", copiedObj);
}, 1500);
结论:
1:建议被拷贝对象的属性为一般键值对类型,不要值的类型为对象
2:如果需要拷贝属性值为对象这种情况,解决办法也很简单,深拷贝一下。看下边例子
这样出来,源对象发生改变,拷贝出来的对象也不会发生变化了。let obj = {
name: "lle",
age: 11,
info: {
class: 1
}
};
let deepCopy = JSON.parse(JSON.stringify(obj)), // ---> 深拷贝
copiedObj = Object.assign({}, deepCopy);
console.log("=========>>>", copiedObj);
setTimeout(() => {
obj.name= "wang";
obj.info.class= 2;
console.log("=========>>>", copiedObj);
}, 1500);
网友评论