一、使用JSON序列化和反序列化
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
该方法适用于大多数的普通对象和数组,但它有一些局限性:
- 不能拷贝非JSON安全的数据,例如undefined、函数、正则表达式等会在序列化过程中丢失;
- 不能处理循环引用的对象,会报错;
- Date对象会被转换成字符串,再转回来会变成字符串
二、递归方法
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
//判断类型 数组|对象
const copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
这种方法可以处理更复杂的对象,包括函数、正则表达式和Date对象。但仍然无法处理循环引用的对象。
三、使用Object.assign()
function deepCopy(obj) {
return Object.assign({}, obj);
}
这种方法类似于浅拷贝,但是对于嵌套对象,它会创建新的对象,从而实现深拷贝。然而,它也有类似于浅拷贝的局限性,不能处理循环引用的对象。
四、使用Object.create()
function deepCopy(obj) {
return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
}
这种方法也类似于浅拷贝,但是对于嵌套对象,它会创建新的对象,从而实现深拷贝。同样地,它也不能处理循环引用的对象。
五、使用第三方库
比如Lodash的_.cloneDeep()
方法
const _ = require('lodash');
const obj = { /* your object */ };
const deepCopyObj = _.cloneDeep(obj);
这些第三方库通常能够处理循环引用和其他特殊情况,但要注意引入额外的依赖和体积增加。
六、jquery实现深拷贝
可以使用jQuery.extend()
方法。这个方法在jQuery中用于合并多个对象,但当只传递一个参数时,它可以实现深拷贝。
// 定义需要深拷贝的对象
const sourceObject = {
name: 'John',
age: 30,
address: {
city: 'New York',
country: 'USA'
},
hobbies: ['reading', 'running']
};
// 使用jQuery.extend()实现深拷贝
const deepCopyObject = $.extend(true, {}, sourceObject);
console.log(deepCopyObject);
请注意,在使用jQuery.extend()
进行深拷贝时,有以下几点需要注意:
- 当原始对象中存在循环引用时,
jQuery.extend()
并不能正确处理,会导致循环引用引发的无限递归,从而导致栈溢出。 jQuery.extend()
方法需要引入jQuery库,如果项目中不使用jQuery,可以选择其他的深拷贝方法。