1.为什么需要拷贝?
数据类型分为原始类型与引用类型,对象是引用类型,栈中存放对象的地址,堆中才存放真实的对象。如果使用简单的赋值运算符来复制对象,复制的只是引用,这会导致修改新的对象时,原对象也随之修改,不具备安全性。
因此为了使两个对象具有独立的空间,修改新对象不会影响原对象,我们可以采用对象拷贝来实现对象的复制。分为浅拷贝与深拷贝两种。
2.浅拷贝
如果对象中属性值的类型是原始类型,就拷贝到独立的空间中,如果是引用类型,只拷贝引用地址
使用for ..in、扩展运算符、Object.assign()实现
// 使用扩展运算符实现浅拷贝
let a = {
name: '小明'
}
let b = { ...a }
console.log(b)
a.name = '小红'
console.log(b.name)
//使用for in 实现浅拷贝
function shallowClone (obj) {
let newObj = {}
for (let key in obj) {
newObj[key] = obj[key]
}
return newObj
}
let copy = shallowClone(a)
console.log(copy)
//使用Object.assign()
let copy2 = {}
Object.assign(copy2, a)
console.log(copy2)
3.深拷贝
使用递归实现
let person = {
name: '张三',
sex: '男',
hobby: ['打球', '游戏'],
job: {
salay: 20
}
}
// 深拷贝与浅拷贝
function deepClone (obj, newObj) {
for (let key in obj) {
if (obj[key] instanceof Array) {
newObj[key] = deepClone(obj[key], [])
}
else if (typeof obj[key] === 'obj') {
newObj[key] = deepClone(obj[key], {})
}
else {
newObj[key] = obj[key]
}
}
return newObj
}
newObj = deepClone(person, {})
console.log(newObj)
使用JSON.stringify与parse实现:
let copy = JSON.parse(JSON.stringify(person))
console.log(copy)
区别:JSON不能拷贝函数