vjjj vjjj - 1 month ago 8
JSON Question

Clone "sub-array" of an array of objects (where objects are deeply nested)

Question 1. I was wondering why


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


give the same nested array of objects as output since
obj.slice(1,3)
is not supposed to clone nested objects properly?


Question 2. Is
JSON.parse(JSON.stringify(obj.slice(1, 3)))
the right way to deep clone a sub-array?



obj details -

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"}]
}]

Answer

Why should it make a difference if you JSON.parse(JSON.stringify()) the result from obj.slice(1, 3), or not? That's what's happening in example 1.

You get obj.slice(1, 3), and you get the same value, passed through a stringify / parse.

Functionally, that's similar to:

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

Regarding question 2:

Yeap.

obj.slice alone can't be used to clone objects. It just copies the contents of an array. In this case, those contents are just pointers to existing objects:

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);

As you can see, editing the foo on b also changes it on a, because both arrays contain pointers to the same object.

That's why you need the JSON.parse(JSON.stringify()).