JavaScript 深拷贝与浅拷贝详解
前言
在 JavaScript 开发中,拷贝对象是一个非常常见的操作。
但很多时候你以为“复制成功了”,其实只是复制了引用,这就会引发很多 Bug。
所以必须搞清楚:
- 什么是浅拷贝
- 什么是深拷贝
- 常见实现方式有哪些
一、浅拷贝是什么?
浅拷贝只会复制对象的第一层属性。
如果属性值还是对象,那么复制的仍然是引用地址。
const obj1 = {
name: 'Tom',
info: {
age: 18
}
};
const obj2 = { ...obj1 };
obj2.info.age = 20;
console.log(obj1.info.age); // 20
说明obj1.info和obj2.info指向同一个对象。
二、常见浅拷贝方式
1)展开运算符
const obj2 = { ...obj1 };
2)Object.assign
const obj2 = Object.assign({}, obj1);
这两种都属于浅拷贝。
三、深拷贝是什么?
深拷贝会递归复制对象的每一层,生成完全独立的新对象。
const obj1 = {
name: 'Tom',
info: {
age: 18
}
};
const obj2 = JSON.parse(JSON.stringify(obj1));
obj2.info.age = 20;
console.log(obj1.info.age); // 18
四、JSON 深拷贝的问题
虽然:
JSON.parse(JSON.stringify(obj))
很常见,但它有局限:
-
不能拷贝函数
-
不能拷贝
undefined -
不能拷贝
Symbol -
不能处理循环引用
-
Date、RegExp会丢失信息
五、手写一个简单深拷贝
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
const result = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key]);
}
}
return result;
}
六、总结
浅拷贝和深拷贝最核心的区别是:
- 浅拷贝:只拷贝第一层
- 深拷贝:递归拷贝所有层级
实际开发中要根据场景选择,不要把浅拷贝误当成深拷贝。