拷贝: 克隆一只哈基米
顾名思义,在js拷贝操作的目的就是按照原来的模板,克隆出一模一样的新对象出来。
它最简单的理解就是克隆出一只一模一样的猫,我们创建了一个新的个体,只是它们各方面都一样而已。
并且拷贝这个意义,只针对引用类型的数据。

浅拷贝
什么是浅拷贝
顾名思义:浅层的拷贝
旧版本的js提供的拷贝方法都比较敷衍,只能进行浅层的拷贝,在拷贝对象内部引用类型数据时,仅仅是将引用数据类型的地址复制来了一份。而不会对这个引用数据类型整体拷贝一份。

浅拷贝带来的问题
因为拷贝出的新对象,内部引用数据类型依赖相同,当对新对象内部引用类型数据进行修改时,会导致原对象的引用数据也受影响 例子:
js
let arr=[1,2,3,4,{age:18}]
let arr2=arr.slice(0)
console.log(arr==arr2)
arr[4].age=10;
console.log(arr2[4].age) // 新对象受原对象影响,所以是一个浅拷贝
实战:手搓一个浅拷贝函数
js
function shallowCopy(obj) {
let o = {};
//for in 循环 遍历 obj的key值
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
//规避对象隐式原型上的属性
o[key] = obj[key]
}
}
return o;
}
深拷贝
什么是深拷贝
顾名思义:深层的拷贝
浅拷贝只是会被拷贝对象的浅层进行拷贝,对于其浅层引用数据类型,则不进行拷贝,仅仅是将引用类型数据的地址复制了一份。所以深拷贝就是顺着引用数据类型层层拷贝,直到所有引用类型数据都被拷贝完成。
由此就可以拷贝出一个不会于原来对象共用同一引用类型数据的对象
常见的深拷贝方法
- 利用structuredClone(obj)方法进行深拷贝
缺点:
- 无法拷贝symbol类型
- 无法拷贝函数
js
const obj = {
name: '哈基米',
age: 18,
like: {
n: {n:'哈气'},
m: '哈呀裤'
},
x:null,
}
let newObj;
//利用structuredClone(obj)方法进行深拷贝
newObj=structuredClone(obj)
obj.like.m="篮球"
console.log(obj,newObj)
- 利用JSON格式转换深拷贝
将对象转为JSON字符串,再由JSON字符串转换为一个新的对象。
缺点:
- 无法处理函数,正则表达式,map等等复杂类型的数据
- 可拷贝数据类型太少
- 原型链丢失:拷贝出的新对象,无法通过原型链调用父对象方法与属性
js
const str= JSON.stringify(obj) //将对象变为一个字符串
//Json.parse() 将字符串转回对象
newObj=JSON.parse(str) //也实现了深拷贝
obj.like.m="篮球"
console.log(obj,newObj)
实战:手搓一个深拷贝
限制:函数正则表达式等
js
function deepCopy(obj) {
let O = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] instanceof Object && !obj[key] instanceof Function) {
O[key] = deepCopy(obj[key]);
}
else {
O[key] = obj[key]
}
}
}
return O;
}