浅拷贝:拷贝基本数据类型为他的值,拷贝引用数据类型为地址,生成新的数据,修改新的数据会影响原数据,实际开发常用的方法有:object.assgin,扩展运算符等等
深拷贝:在内存中开辟一个新的栈空间保存新的数据,修改新数据不会影响到原数据,开发中常用的方法有:loadsh 中的_.cloneDeep()方法,JSON.stringify()
下面首先借助两张图,可以更加清晰看到浅拷贝与深拷贝的区别
从上图发现,浅拷贝和深拷贝都创建出一个新的对象,但在复制对象属性的时候,它两者的行为就不一样
浅拷贝只复制属性指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,修改对象属性会影响原对象
// 浅拷贝
const obj1 = {
name: 'init',
arr: [1, [2, 3], 4],
}
const obj3={}
Object.assign(obj3, obj1) // 一个浅拷贝方法
obj3.name = 'update'
obj3.arr[1] = [5, 6, 7] // 新旧对象还是共享同一块内存
console.log('obj1', obj1) // obj1 { name: 'init', arr: [ 1, [ 5, 6, 7 ], 4 ] }
console.log('obj3', obj3) // obj3 { name: 'update', arr: [ 1, [ 5, 6, 7 ], 4 ] }
但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
const obj = { name: '老王', size: '180cm', address: { province: '北京' } }
// 深拷贝函数,写之前,我们先用for...in
function deepClone(old) {
const newObj = {}
// newObj.name = '张三'
// newObj['name'] = '张三'
for (let key in old) { // key循环3次 name/size/address
// 访问对象上面的属性,只能用中括号,不能用., 因为中括号里面可以放变量
// newObj.name = obj.name
// newObj.address = obj.address
newObj[key] = old[key]
}
return newObj
}
// 写代码,不是直接去函数里面写, 要先想函数怎么用,再去里面慢慢填
const newObj = deepClone(obj)
console.log(newObj);
前提为拷贝类型为引用类型的情况下:
浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址
深拷贝是递归拷贝深层次,属性为对象时,深拷贝是新开栈,两个对象指向不同的地址