讲师中心 微信公众号
AI工具推荐 视频效率加速

javascript怎么克隆多维数组

雨萱酱_6196

雨萱酱_6196

发布时间:2025-07-29 09:08:01

|

567人浏览过

|

来源于php中文网

原创

json.parse(json.stringify(arr))不能完全克隆多维数组,因为它无法处理函数、undefined、symbol、bigint、date、regexp及循环引用,会导致数据丢失或报错;2. 推荐使用structuredclone()进行深度克隆,因为它能正确处理date、regexp、map、set、arraybuffer等复杂类型,并支持循环引用,是现代环境下的首选方案;3. 编写通用深度克隆函数可通过递归实现,结合weakmap处理循环引用,并针对不同对象类型(如date、regexp、map、set)分别克隆,从而应对structuredclone()不支持的场景或旧环境需求,确保所有嵌套层级被独立复制。

javascript怎么克隆多维数组

在JavaScript中克隆多维数组,核心在于实现“深拷贝”。简单地使用赋值操作符或者像 slice()concat() 这样的方法,只能实现“浅拷贝”,这意味着数组的子元素(如果它们是对象或数组)仍然会引用原始内存地址。要真正克隆多维数组,你需要确保所有嵌套的层级都被独立复制,而不是仅仅复制引用。

javascript怎么克隆多维数组

解决方案

要深度克隆一个JavaScript多维数组,有几种方法,每种都有其适用场景和局限性。

一个常见且快速的方法是利用 JSON.parse(JSON.stringify(arr))。这种方式的原理是先将数组转换为JSON字符串,再将字符串解析回新的JavaScript对象。因为JSON字符串不包含引用,所以解析出的新对象是完全独立的。

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

javascript怎么克隆多维数组

然而,这种方法并非万能。它有明显的局限性:

  • 它无法处理函数、undefinedSymbolBigInt 类型的数据,这些会在转换过程中丢失。
  • Date 对象会被转换为ISO格式的字符串,而不是保持为 Date 对象。
  • RegExp 对象会变成空对象 {}
  • 它不能处理循环引用(即对象内部引用了自身或其父级),会导致报错。

对于更健壮的深拷贝,现代JavaScript环境提供了 structuredClone() API。这是一个更推荐的方法,它基于结构化克隆算法,能处理更多的数据类型,包括 MapSetDateRegExpArrayBuffer 等,并且能够正确处理循环引用。

javascript怎么克隆多维数组

如果需要更精细的控制,或者要兼容不支持 structuredClone() 的旧环境,编写一个递归的深拷贝函数是必要的。这个函数可以根据需要定制,例如决定如何处理函数、DOM节点等特殊类型。

仿UC浏览器官方网站全屏jQuery幻灯片
仿UC浏览器官方网站全屏jQuery幻灯片

仿UC浏览器官方网站全屏jQuery幻灯片

下载

JSON.parse(JSON.stringify(arr)) 真的能完全克隆多维数组吗?

说实话,我个人觉得这个方法更像是一个“快速但不完美”的技巧,而不是一个通用的解决方案。它确实能处理大多数由数字、字符串、布尔值、纯对象和数组组成的简单多维数组。比如,你有一个全是数字和字符串构成的二维数组,或者嵌套了几层的纯数据对象,JSON.parse(JSON.stringify(arr)) 跑起来是没问题的,而且效率还不错。

但问题在于,真实世界的JavaScript数据结构往往比我们想象的要复杂。一旦你的数组里混入了 Date 对象(它们会被转成字符串,你就失去了 Date 对象的所有方法)、undefined(它们会直接消失)、函数(同样消失)、或者更糟的,如果你有循环引用(比如对象A引用了对象B,同时对象B又引用了对象A),那么 JSON.stringify 就会直接抛出错误。这就像你试图把一个活生生的人塞进一个只能装扁平照片的信封里,结果肯定是不行的。所以,它的适用范围其实相当有限,只适合那些“纯粹”的数据结构。

推荐使用 structuredClone() 进行深度克隆吗?

绝对推荐!如果你的目标环境支持 structuredClone()(目前主流浏览器和Node.js都支持得很好),那么这无疑是进行深度克隆的首选。我个人在项目中,只要条件允许,都会优先考虑它。

为什么呢?因为它太方便了,而且功能强大。它不仅能正确处理我们前面提到的 Date 对象(克隆后依然是 Date 对象),还能处理 RegExpMapSetArrayBufferBlobFile 等多种复杂类型。更重要的是,它能够优雅地处理循环引用,不会像 JSON.stringify 那样直接报错。这极大地减少了我们作为开发者需要考虑的边界情况。

用它的时候,感觉就像是JavaScript终于给了一个官方的、一劳永逸的深拷贝方案。你不需要再去找各种第三方库,也不用自己手写复杂的递归逻辑。它就是为了这个目的而设计的,并且被广泛测试和优化过。当然,它也有一些不能克隆的东西,比如函数(函数本质上是行为,而不是数据,通常我们不克隆函数,而是共享引用),或者DOM节点。但对于绝大多数数据结构的深拷贝需求,structuredClone() 都是一个非常可靠且高效的选择。

如何编写一个更通用的深度克隆函数来应对复杂场景?

structuredClone() 不可用(比如旧环境),或者你需要处理一些 structuredClone() 无法处理的特殊类型(例如你想克隆函数,或者有特定的自定义对象处理逻辑),手写一个递归的深拷贝函数就变得不可避免了。这确实需要一些思考,特别是要处理好循环引用,否则很容易陷入无限递归的泥潭。

一个相对健壮的深拷贝函数,通常会用到一个 MapWeakMap 来存储已经克隆过的对象,以避免循环引用导致的死循环。

function deepClone(obj, hash = new WeakMap()) {
    // 基础类型或null,直接返回
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }

    // 处理特殊内置对象
    if (obj instanceof Date) {
        return new Date(obj);
    }
    if (obj instanceof RegExp) {
        return new RegExp(obj);
    }
    if (obj instanceof Map) {
        const newMap = new Map();
        for (const [key, value] of obj) {
            newMap.set(deepClone(key, hash), deepClone(value, hash));
        }
        return newMap;
    }
    if (obj instanceof Set) {
        const newSet = new Set();
        for (const value of obj) {
            newSet.add(deepClone(value, hash));
        }
        return newSet;
    }

    // 处理循环引用:如果该对象已被克隆过,直接返回克隆后的对象
    if (hash.has(obj)) {
        return hash.get(obj);
    }

    // 根据是数组还是普通对象创建新的容器
    const clone = Array.isArray(obj) ? [] : {};
    // 将新创建的克隆对象存入hash,以便处理循环引用
    hash.set(obj, clone);

    // 递归克隆所有属性
    for (const key in obj) {
        // 确保只处理对象自身的属性,而不是原型链上的
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            clone[key] = deepClone(obj[key], hash);
        }
    }

    return clone;
}

// 示例使用
const originalArray = [
    1,
    'hello',
    { a: 1, b: [2, 3] },
    new Date(),
    new RegExp(/abc/g),
    new Map([['key1', 'value1']]),
    new Set([10, 20])
];

originalArray[2].selfRef = originalArray; // 制造一个循环引用

const clonedArray = deepClone(originalArray);

console.log(clonedArray);
console.log(clonedArray[2].selfRef === clonedArray); // 检查循环引用是否被正确处理
console.log(clonedArray[3] instanceof Date); // 检查Date对象是否被正确克隆
console.log(clonedArray[4] instanceof RegExp); // 检查RegExp对象是否被正确克隆
console.log(clonedArray[5] instanceof Map); // 检查Map对象是否被正确克隆

这个函数考虑了基本类型、日期、正则表达式、Map、Set以及最重要的循环引用。它使用 WeakMap 作为 hash 表,这样当原始对象不再被引用时,垃圾回收机制可以清理掉 WeakMap 中的对应条目,避免内存泄漏。编写这样的函数,你才能真正掌控深拷贝的每一个细节,应对那些“不走寻常路”的数据结构。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

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

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

1955

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2642

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

916

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2939

2025.09.10

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

3776

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

2261

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

6102

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

772

2023.08.11

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

20

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn