深拷贝、浅拷贝
nan_kliang 5/10/2023 JS
# 浅拷贝
浅拷贝只拷贝对象的第一层属性,如果属性是引用类型,拷贝的是引用而不是实际的对象。
let obj1 = {
a: 1,
b: { c: 2 }
}
// 使用Object.assign进行浅拷贝
let shallowCopy = Object.assign({}, obj1)
// 修改shallowCopy中的引用类型属性
shallowCopy.b.c = 3
console.log(obj1) // 输出: { a: 1, b: { c: 3 } }
console.log(shallowCopy) // 输出: { a: 1, b: { c: 3 } }
shallowCopy 和 obj1 的 b 属性指向同一个对象,因此修改 shallowCopy.b.c 也会影响 obj1.b.c。
# 深拷贝
深拷贝会递归地拷贝对象的所有层级,包括嵌套的对象和数组,确保拷贝后的对象和原对象没有任何引用关系。
// 一个简单的深拷贝函数实现
function deepClone(obj) {
if (obj === null) return null
let clone = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
clone[key] = deepClone(obj[key])
} else {
clone[key] = obj[key]
}
}
}
return clone
}
let obj1 = {
a: 1,
b: { c: 2 }
}
// 使用deepClone进行深拷贝
let deepCopy = deepClone(obj1)
// 修改deepCopy中的引用类型属性
deepCopy.b.c = 3
console.log(obj1) // 输出: { a: 1, b: { c: 2 } }
console.log(deepCopy) // 输出: { a: 1, b: { c: 3 } }
deepCopy 和 obj1 完全独立,修改 deepCopy.b.c 不会影响 obj1.b.c。
# 使用现代库或方法
在实际开发中,为了简化深拷贝的过程,通常会使用现成的库或方法,如lodash的_.cloneDeep()或JSON的序列化和反序列化方法:
let obj1 = {
a: 1,
b: { c: 2 }
};
// 使用lodash进行深拷贝
let deepCopy = _.cloneDeep(obj1)
// 或者使用JSON.parse和JSON.stringify
let deepCopy = JSON.parse(JSON.stringify(obj1))
// 然后可以安全地修改deepCopy
deepCopy.b.c = 3
注意:使用JSON.parse和JSON.stringify方法进行深拷贝有一些局限性,它不能处理函数和循环引用的情况。