【问题标题】:Clone "sub-array" of an array of objects (where objects are deeply nested)克隆对象数组的“子数组”(对象嵌套很深)
【发布时间】:2017-02-22 04:02:19
【问题描述】:

问题 1. 我想知道为什么

JSON.parse(JSON.stringify(obj.slice(1, 3))) and
obj.slice(1,3) 

给出与输出相同的嵌套对象数组,因为obj.slice(1,3) 不应该正确克隆嵌套对象?

问题 2. JSON.parse(JSON.stringify(obj.slice(1, 3))) 是深度克隆子阵列的正确方法吗?

obj 详细信息 -

var obj= [{ name: "wfwfwfw.)csdfsd",
        tags: [ "dfbdf>>sfdfds", "fsdfsdf&fsfd" ],
        newer: { first: "this'one", second: ["that>.one", "another.'one"], third: {something: "some/>fded", newthing: "ddasd..>sqw"}     },
        final: [ {gh: "ty/fgfg", hj: "rt((ssds"}, {gh: "dqqq...g", hj: "gnm))s"} ]
},
{ name: "wfwfwwwwwwfw.)csdfsd",
        tags: [ "dfbdf>>sfdfds", "fsdfsdf&fsfd" ],
        newer: { first: "this'one", second: ["that>.one", "another.'one"], third: {something: "some/>fded", newthing: "ddasd..>sqw"} },
        final: [ {gh: "ty/fgfg", hj: "rt((ssds"}, {gh: "dqqq...g", hj: "gnm))s"}]
},
{ name: "aa.)csdfsd",
        tags: [ "dfbdf>>sfdfds", "fsdfsdf&fsfd" ],
        newer: { first: "this'one", second: ["that>.one", "another.'one"], third: {something: "some/>fded", newthing: "ddasd..>sqw"} },
        final: [ {gh: "ty/fgfg", hj: "rt((ssds"}, {gh: "dqqq...g", hj: "gnm))s"}]
},
{ name: "nn.)csdfsd",
        tags: [ "dfbdf>>sfdfds", "fsdfsdf&fsfd" ],
        newer: { first: "this'one", second: ["that>.one", "another.'one"], third: {something: "some/>fded", newthing: "ddasd..>sqw"} },
        final: [ {gh: "ty/fgfg", hj: "rt((ssds"}, {gh: "dqqq...g", hj: "gnm))s"}]
}]

【问题讨论】:

  • obj.slice(1,3)JSON.parse(JSON.stringify(obj.slice(1, 3))) 给出相同的输出,因为它们做的事情完全相同。到达那里需要更长的时间。
  • 是不是意味着obj.slice(1,3)可以用于深度克隆对象?
  • 没有。 slice 只是复制引用。 obj,slice 返回的结果中的引用与obj 中的引用相同。 JSON.stringify 从您的对象创建字符串,然后JSON.parse 将字符串转换为具有相同结构的新对象。你得到相同的输出,因为它们是副本。没有办法区分它们(除了它们在内存中的地址不同,即使用 ===)

标签: javascript arrays json object clone


【解决方案1】:

如果您JSON.parse(JSON.stringify()) 来自obj.slice(1, 3) 的结果,为什么它会有所不同?这就是示例 1 中发生的情况。

你得到obj.slice(1, 3),你得到相同的值,通过字符串化/解析。

在功能上类似于:

var foo = 'bar';
console.log(foo);
console.log(JSON.parse(JSON.stringify(foo)));

关于问题2:

是的。

obj.slice 不能单独用于克隆对象。它只是复制数组的内容。在这种情况下,这些内容只是指向现有对象的指针:

var a = [{foo: 'bar'}, {x: 'y'}];
var b = a.slice(0,1) 

console.log('B:', b);

b[0].foo = 'test';

console.log('After modification:');
console.log('A:', a);
console.log('B:', b);

如您所见,在b 上编辑foo 也会在a 上更改它,因为两个数组都包含指向相同 对象的指针。

这就是您需要JSON.parse(JSON.stringify()) 的原因。

【讨论】:

  • 那么克隆对象子数组的最佳方法是什么?
  • 但是 JSON.parse(JSON.stringify(obj)) 会克隆整个数组。如果我只想将 obj[0]、obj[1]、obj[2] 克隆到一个新数组中怎么办?
  • 然后你首先用slice选择合适的数组条目
  • 那么,我猜JSON.parse(JSON.stringify(obj.slice(0, 3))) 是深度克隆子数组的正确方法?
  • 在这种情况下,您不应该写 No 作为对问题 2 的回答(在您的回答中)
【解决方案2】:

Array.slice() 不做深拷贝,因此不适合多维数组。

当一个真值作为初始参数传递时,jQuery 的 extend 方法会执行深层复制。

// Deep copy
var newArray = jQuery.extend(true, [], oldArray);

类似帖子here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 2023-01-13
    • 1970-01-01
    • 2019-01-29
    • 2016-05-18
    相关资源
    最近更新 更多