首页 > web前端 > js教程 > 正文

JavaScript实现深拷贝的几种方案对比_js编程实践

狼影
发布: 2025-11-16 22:43:02
原创
969人浏览过
深拷贝需根据场景选择方法:JSON方法简洁但不支持函数、循环引用等;手动递归可定制但复杂;结构化克隆支持多数内置对象但异步;Lodash最稳定但增加依赖。

javascript实现深拷贝的几种方案对比_js编程实践

深拷贝在JavaScript中是一个常见但容易出错的操作。它指的是创建一个新对象,其属性和嵌套对象的值都与原对象完全独立。修改新对象不会影响原始对象。实现深拷贝有多种方式,每种都有其适用场景和局限性。下面介绍几种主流方法,并进行对比分析。

1. JSON.parse(JSON.stringify())

这是最简单、最常用的深拷贝方法之一。

优点:
  • 语法简洁,一行代码即可完成。
  • 能处理常见的数据类型:对象、数组、字符串、数字、布尔值等。
缺点:
  • 无法处理函数、undefined、Symbol,这些值会被忽略。
  • 不能复制循环引用,会报错。
  • Date对象会被转换为字符串。
  • Map、Set、RegExp等特殊对象无法正确复制。
  • 原型链上的属性不会被保留。

适合场景:仅用于纯数据对象(POJO),且不包含复杂类型或循环引用的情况。

2. 手动递归实现深拷贝

通过递归遍历对象属性,逐层复制。

立即学习Java免费学习笔记(深入)”;

示例代码:
function deepClone(obj, seen = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (seen.has(obj)) return seen.get(obj); // 处理循环引用
<p>let clone;
if (obj instanceof Date) {
clone = new Date(obj);
} else if (obj instanceof RegExp) {
clone = new RegExp(obj);
} else if (Array.isArray(obj)) {
clone = obj.map(item => deepClone(item, seen));
} else {
clone = {};
seen.set(obj, clone);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], seen);
}
}
}
return clone;
}</p>
登录后复制
优点:
  • 可自定义处理各种数据类型。
  • 支持循环引用(使用WeakMap)。
  • 灵活性高,可根据需求扩展。
缺点:
  • 代码量较大,需要考虑多种边界情况。
  • 手动维护类型判断逻辑,容易遗漏。

适合场景:需要精确控制拷贝行为,或处理复杂对象结构时。

3. 使用结构化克隆算法(Structured Clone)

HTML5提供的结构化克隆算法可用于深拷贝,可通过MessageChannel或postMessage间接使用。

Calliper 文档对比神器
Calliper 文档对比神器

文档内容对比神器

Calliper 文档对比神器 28
查看详情 Calliper 文档对比神器
示例:
function structuredClone(obj) {
  return new Promise(resolve => {
    const { port1, port2 } = new MessageChannel();
    port2.onmessage = e => resolve(e.data);
    port1.postMessage(obj);
  });
}
// 注意:需异步调用
structuredClone(obj).then(clone => { /* 使用clone */ });
登录后复制
优点:
  • 浏览器原生支持,性能较好。
  • 支持多数内置对象(Date、RegExp、Map、Set、Blob等)。
  • 自动处理循环引用。
缺点:
  • 不支持函数和undefined。
  • 必须异步调用,使用不便。
  • 某些类型仍受限(如Error对象、DOM节点)。

适合场景:在现代浏览器中处理复杂数据结构,且可以接受异步操作。

4. 利用第三方库(如 Lodash)

Lodash 提供了 _.cloneDeep 方法,功能完善且经过充分测试。

示例:
const _ = require('lodash');
const cloned = _.cloneDeep(obj);
登录后复制
优点:
  • 稳定可靠,覆盖大多数边缘情况。
  • 支持大量JavaScript类型(包括Map、Set、Date、RegExp等)。
  • 处理循环引用无压力。
缺点:
  • 引入额外依赖,增加包体积。
  • 对于简单项目可能“杀鸡用牛刀”。

适合场景:项目已使用Lodash,或对深拷贝稳定性要求极高。

总结对比

不同方案各有侧重:

  • JSON方法最轻便,但限制多,仅适用于简单数据。
  • 手动递归灵活可控,适合定制化需求。
  • 结构化克隆接近原生,但异步使用略麻烦。
  • Lodash等库最稳健,推荐在生产环境使用。

选择哪种方式,取决于你的具体需求:是否涉及复杂类型、是否有循环引用、是否允许异步、是否已有工具库等。

基本上就这些。理解每种方法的边界,才能在实际开发中做出合理选择。

以上就是JavaScript实现深拷贝的几种方案对比_js编程实践的详细内容,更多请关注php中文网其它相关文章!

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号