什么是浅拷贝?
创建一个新的对象,来接收原本对象的值,如果对象的数据类型是基本数据类型,复制的就是基本数据类型的值给了新对象, 如果是引用数据类型,那么相当于是复制了一个地址,如果其中的一个改变了里面的值,会影响到另一个对象(也可以理解为只有第一层的对象不会受影响)
let obj = {
name: '张三',
age: 18,
info: {
width: 100,
height: 200
}
}
let newObj = {}
for(let key in obj) {
newObj[key] = obj[key]
}
newObj.age = 28
newObj.info.width = 150 // 这里就会影响到另外一个对象
什么是深拷贝?
浅拷贝只是创建了一个新的对象,复制了原有对象基本数据类型的值,而引用数据只拷贝了一层属性,再深层的还是会互相影响,深拷贝是将原对象从原内存中完全拷贝出来给目标对象,并从堆内存中开辟一个全新的空间存放新对象,且新对象的修改不会影响原对象,两者实现完全的分离
let obj = {
name: '张三',
age: 18,
info: {
width: 100,
height: 200
}
}
let newObj = {}
function deepClone(target,origin) { // target代表目标对象,origin代表原始对象
for(let key in origin) {
// 根据 key 的数据类型的不同走不同的分支
if(object.prototype.toString.call(origin[key]) === object Object) {
// 说明当前这个 key 是一个对象
target[key] = {}
deepClone(target[key],origin[key])
} else if(object.prototype.toString.call(origin[key]) === object Array){
// 说明当前这个 key 是一个数组
target[key] = []
deepClone(target[key],origin[key])
} else{
// 走这个分支说明是普通数据类型
target[key] = origin[key]
}
}
}
deepClone(newObj,obj)
console.log(newObj)
代码分析:
调用 deepClone时,第一个参数是一个空对象,第二个参数内部有三个属性,分别是name,age,info,其中info是一个对象
函数在开始执行的时候,首先会先执行一个 for...in 遍历第二个参数
for...in 循环第一次执行, key === 'name',origin[key] === '张三'
开始运行函数内部的分支语句,因为当前 value 类型为 string,那么会走最后一个else分支
那么就是直接将 target[key] = origin[key],相当于 newObj.name = '张三'
for...in 循环第二次执行,key === 'age',origin[key] === 18
开始运行函数内部的分支语句,因为当前 value 类型为 number,那么会走最后一个else分支
那么就是直接将 target[key] === origin[key],相当于 newObj.age = 18
for...in 循环第三次执行,key === info,origin[key] === {width:100,height:200}
开始运行函数内部的分支语句,因为当前 value 类型为 object,那么会走第一个分支
分支内部的代码
1. target[key] = {} {name:'张三',age:18,info:{}}
2.deepClone(target[key],origin[key])
调用 deepClone,第一个参数是一个空对象,第二个参数是一个对象,有两个属性,分别是width,height
函数在执行的时候,会先执行一个 for...in 循环遍历第二个参数
for...in 第一次执行,key === 'width',origin[key] === 100
开始运行循环内部的分支语句,因为当前 value 的值为 number,所以会走最后一个分支,
那么就是直接将 target[key] = origin[key],相当于 target.width = 100
for...in 第二次执行,key === 'height',origin[key] === 200
开始运行函数内部的分支语句,因为当前 value 的值为 number,那么会走最后一个else分支
那么就是直接将 target[key] = origin[key],相当于 target.height = 200
这两轮for执行完毕后,target.info === {width:100,height:200}