可能遇到的陷阱
- 浅拷贝问题:当直接使用赋值操作符
=
对包含嵌套数组和对象的结构进行赋值时,可能会出现浅拷贝。例如,若想复制 obj.arr
中的子数组 [1, 2]
,简单的 newArr = obj.arr[0]
只是创建了一个指向原数组的引用,对 newArr
的修改会影响到 obj.arr[0]
。
- 对象引用问题:对于
obj.arr
中的对象 { key: 'value' }
,同样存在引用问题。如果赋值时没有进行深拷贝,对新对象的修改会反映到原对象上。
避免陷阱的代码实现
- 使用
JSON.parse(JSON.stringify())
进行深拷贝(局限性:不能处理函数、正则等特殊对象)
const obj = { arr: [[1, 2], { key: 'value' }] };
// 深拷贝整个obj
const newObj = JSON.parse(JSON.stringify(obj));
// 修改新对象不会影响原对象
newObj.arr[0][0] = 10;
newObj.arr[1].key = 'newValue';
console.log(obj);
console.log(newObj);
- 使用
lodash
库的 cloneDeep
方法
const _ = require('lodash');
const obj = { arr: [[1, 2], { key: 'value' }] };
// 深拷贝整个obj
const newObj = _.cloneDeep(obj);
// 修改新对象不会影响原对象
newObj.arr[0][0] = 10;
newObj.arr[1].key = 'newValue';
console.log(obj);
console.log(newObj);
- 手动实现深拷贝函数(较复杂,可处理部分特殊对象)
function deepClone(obj) {
if (typeof obj!== 'object' || obj === null) {
return obj;
}
let cloneObj;
if (Array.isArray(obj)) {
cloneObj = [];
for (let i = 0; i < obj.length; i++) {
cloneObj[i] = deepClone(obj[i]);
}
} else {
cloneObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key]);
}
}
}
return cloneObj;
}
const obj = { arr: [[1, 2], { key: 'value' }] };
// 深拷贝整个obj
const newObj = deepClone(obj);
// 修改新对象不会影响原对象
newObj.arr[0][0] = 10;
newObj.arr[1].key = 'newValue';
console.log(obj);
console.log(newObj);