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

当我第一次想到这个问题的时候,我就想到了

var clonedNodesArray = nodesArray.clone()

并搜索如何在JavaScript中克隆对象的信息。我确实在Stack Overflow上找到了一个问题(同样由@JohnResig回答),他指出用jQuery你可以做到

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

克隆对象。虽然我尝试了这个,但这只复制了数组中对象的引用。如果我

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

nodesArray[0]和clonedNodesArray[0]的值将显示为“绿色”。然后我尝试了

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

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

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


当前回答

function deepCloneArray(array) {
    return Array.from(Object.create(array));
}

其他回答

我可能有一种简单的方法来做到这一点,而不需要做痛苦的递归,也不知道有关对象的所有细节。使用jQuery,只需使用jQuery $. tojson (myObjectArray)将对象转换为JSON,然后将JSON字符串计算回对象。砰!搞定了,搞定了!问题解决了。:)

var oldObjArray = [{ Something: 'blah', Cool: true }];
var newObjArray = eval($.toJSON(oldObjArray));

在我的例子中,我有一个包含许多嵌套对象的数组,所以其他答案不适用于我的用例。

我现在使用的是npm包deep-copy-all:

npm i deep-copy-all
const deepCopy = require("deep-copy-all")

const copy = deepCopy(original)
copy[0].users[0].payments[0].product.price = 10

console.log(copy[0].users[0].payments[0].product.price) // 10
console.log(original[0].users[0].payments[0].product.price) // 5

jQuery:

var target = [];
$.each(source, function() {target.push($.extend({}, this));});

忘记eval()(它是JavaScript中最常被误用的特性,会使代码变慢)和slice(0)(只适用于简单的数据类型)

这对我来说是最好的解决方案:

Object.prototype.clone = function() {
  var myObj = (this instanceof Array) ? [] : {};
  for (i in this) {
    if (i != 'clone') {
        if (this[i] && typeof this[i] == "object") {
          myObj[i] = this[i].clone();
        }
        else
          myObj[i] = this[i];
    }
  }
  return myObj;
};

我想我们可以做到->

let a = [{name: "mike"}, {name: "ron"}];
let copy_a = [...a];