一、前言
之前在前面一篇学习了赋值,浅拷贝和深拷贝。介绍了这三者的相关知识和区别。
传送门:https://www.mwcxs.top/page/592.html
本文会介绍浅拷贝Object.assign()的实现原理,然后咱们试着实现一个浅拷贝。
二、浅拷贝Object.assign()
什么是浅拷贝?浅拷贝就是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。
浅拷贝Object.assign()是什么?主要将所有可枚举属性的值从一个或者多个数据源对象复制到目标对象,同时返回目标对象。
语法规则:
Object.assign(target,...sources)
其中target是目标对象,source是源对象,可以是多个,修改返回的是目标对象target。
1、如果目标对象中的属性具有相同的属性键,则属性将被源对象中的属性覆盖;
2、源对象的属相将类似覆盖早先的属性。
强调两点:
1、可枚举的属性(自有属性)
2、string或者symbol类型是可以被直接分配的
2.1栗子1
浅拷贝就是拷贝第一层的基本类型值,以及第一层的引用类型地址。
// saucxs
// 第一步
let a = {
name: "advanced",
age: 18
}
let b = {
name: "saucxs",
book: {
title: "You Don't Know JS",
price: "45"
}
}
let c = Object.assign(a, b);
console.log(c);
// {
// name: "saucxs",
// age: 18,
// book: {title: "You Don't Know JS", price: "45"}
// }
console.log(a === c);
// true
// 第二步
b.name = "change";
b.book.price = "55";
console.log(b);
// {
// name: "change",
// book: {title: "You Don't Know JS", price: "55"}
// }
// 第三步
console.log(a);
// {
// name: "saucxs",
// age: 18,
// book: {title: "You Don't Know JS", price: "55"}
// }
分析:
1、第一步中,使用Object.assign把源对象b的值复制到目标对象a中,这里把返回值定义为对象c,可以看出b会替换掉a中具有相同键的值,即如果目标对象a中的属性具有相同的键,则属相将被源对象b中的属性覆盖。返回的对象c就是目标对象a。
2、第二步中,修改源对象b的基本类型值(name)和引用类型值(book)。
3、第三步中,浅拷贝之后目标对象a的基本类型值没有改变,但是引用类型值发生了改变,因为Object.assign()拷贝的是属性值。加入源对象的属性值是一个指向对象的引用,只拷贝那个引用地址。
2.2栗子2
string类型和symbol类型的属性都会被拷贝,而且不会跳过那些值为null或undefined的源对象。
// saucxs
// 第一步
let a = {
name: "saucxs",
age: 18
}
let b = {
b1: Symbol("saucxs"),
b2: null,
b3: undefined
}
let c = Object.assign(a, b);
console.log(c);
// {
// name: "saucxs",
// age: 18,
// b1: Symbol(saucxs),
// b2: null,
// b3: undefined
// }
console.log(a === c);
// true