小编典典

如何在 JavaScript 中克隆对象数组?

all

…每个对象还具有对同一数组中其他对象的引用?

当我第一次想到这个问题时,我只是想到了类似的东西

var clonedNodesArray = nodesArray.clone()

将存在并搜索有关如何在 JavaScript 中克隆对象的信息。

var clonedNodesArray = jQuery.extend({}, nodesArray);

克隆一个对象。不过我试过了,这只复制了数组中对象的引用。所以如果我

nodesArray[0].value = "red"
clonedNodesArray[0].value = "green"

nodesArray[0] 和 clonedNodesArray[0] 的值都将变成“绿色”。然后我尝试了

var clonedNodesArray = jQuery.extend(true, {}, nodesArray);

它深度复制了一个对象,但我分别从FirebugOpera
Dragonfly收到了“
递归过多 ”和“
控制堆栈溢出”消息。

你会怎么做?这是不应该做的事情吗?在 JavaScript 中是否有可重用的方法?


阅读 100

收藏
2022-03-10

共1个答案

小编典典

您的浅拷贝的问题是所有对象都没有被克隆。虽然对每个对象的引用在每个数组中都是唯一的,但一旦您最终抓住它,您将处理与以前相同的对象。您克隆它的方式没有任何问题…使用
Array.slice() 会产生相同的结果。

您的深层副本出现问题的原因是您最终得到了循环对象引用。Deep 会尽可能深,如果你有一个圆圈,它会一直无限下去,直到浏览器晕倒。

如果数据结构不能表示为有向无环图,那么我不确定您是否能够找到用于深度克隆的通用方法。循环图提供了许多棘手的极端情况,并且由于它不是一种常见的操作,我怀疑是否有人编写了完整的解决方案(如果它甚至可能

它可能不会!但我现在没有时间尝试编写严格的证明。)。我在这个页面上发现了一些关于这个问题的好评论。

如果您需要具有循环引用的对象数组的深层副本,我相信您将不得不编写自己的方法来处理您的专用数据结构,例如它是一个多遍克隆:

  1. 在第一轮,克隆所有不引用数组中其他对象的对象。跟踪每个对象的起源。
  2. 在第二轮中,将对象连接在一起。
2022-03-10