javascript 深度复制对象
时间: 2024-12-27 11:30:04 浏览: 9
### 实现 JavaScript 对象的深拷贝
在 JavaScript 中,深拷贝意味着创建一个新对象,该对象与原对象具有相同的内容但不共享任何引用。这确保了对新对象的操作不会影响到原来的对象。
#### 方法一:手动递归实现深拷贝
通过编写自定义函数来遍历并复制对象中的每一个属性,对于复杂的数据类型(如数组或对象),则递归调用此方法继续深入处理:
```javascript
function deepCopy(obj) {
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === "object" && obj[key] !== null) {
copy[key] = deepCopy(obj[key]);
} else {
copy[key] = obj[key];
}
}
}
return copy;
}
```
这种方法可以有效地处理大多数情况下的简单数据结构[^1]。
#### 方法二:利用 `JSON` 序列化和反序列化
另一种常见的做法是先将对象转换成字符串形式再解析回对象,这样也能达到深拷贝的效果:
```javascript
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
```
不过需要注意的是,这种方式并不适用于所有类型的值,比如它会丢失函数、正则表达式以及特殊符号键等信息,并且无法正确处理循环引用的情况[^2]。
#### 完整版深拷贝解决方案
考虑到上述两种方案各自的局限性,这里给出一种更全面的实现方式,能够更好地应对各种特殊情况,包括但不限于函数、日期、错误实例、正则表达式和支持循环引用检测等功能:
```javascript
function completeDeepClone(source, hash = new WeakMap()) {
if (!source || typeof source !== 'object') return source;
// 处理 Date 和 RegExp 类型
if (source instanceof Date) return new Date(source);
if (source instanceof RegExp) return new RegExp(source);
// 防止循环引用导致死循环
if (hash.has(source)) return hash.get(source);
const target = Array.isArray(source) ? [] : {};
hash.set(source, target);
Object.keys(source).forEach((key) => {
if (source[key] && typeof source[key] === 'object') {
target[key] = completeDeepClone(source[key], hash);
} else {
target[key] = source[key];
}
});
return target;
}
```
这段代码不仅解决了基本类型的深拷贝问题,还特别针对某些内置类进行了优化处理,同时加入了防止无限递归的安全机制[^3]。
阅读全文