推荐答案
// www.javascriptcn.com code example
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof RegExp) {
return new RegExp(obj);
}
if (Array.isArray(obj)) {
const arrCopy = [];
for (let i = 0; i < obj.length; i++) {
arrCopy[i] = deepClone(obj[i]);
}
return arrCopy;
}
const objCopy = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
objCopy[key] = deepClone(obj[key]);
}
}
return objCopy;
}本题详细解读
1. 基本思路
深拷贝的核心思想是递归地复制对象的所有属性,包括嵌套的对象和数组。我们需要处理以下几种情况:
- 基本类型(如
number,string,boolean等):直接返回。 null和undefined:直接返回。Date对象:创建一个新的Date对象,复制时间戳。RegExp对象:创建一个新的RegExp对象,复制正则表达式。- 数组:递归地复制数组中的每个元素。
- 对象:递归地复制对象的每个属性。
2. 代码解析
- 基本类型和
null检查:如果obj是基本类型或null,直接返回obj。 Date对象处理:如果obj是Date对象,创建一个新的Date对象并复制时间戳。RegExp对象处理:如果obj是RegExp对象,创建一个新的RegExp对象并复制正则表达式。- 数组处理:如果
obj是数组,创建一个新数组,并递归地复制每个元素。 - 对象处理:如果
obj是对象,创建一个新对象,并递归地复制每个属性。
3. 注意事项
- 循环引用:这个实现没有处理循环引用的情况。如果对象中存在循环引用,会导致无限递归。可以通过使用
WeakMap来存储已经拷贝过的对象来解决这个问题。 - 性能:深拷贝是一个相对耗时的操作,尤其是在处理大型对象时。在实际应用中,应尽量避免不必要的深拷贝。
4. 扩展
- 处理循环引用:可以通过引入
WeakMap来存储已经拷贝过的对象,避免无限递归。 - 处理更多类型:可以根据需要扩展
deepClone函数,支持更多类型的深拷贝,如Map、Set等。