Skip to content

Instantly share code, notes, and snippets.

@rafaelbernard
Created July 24, 2019 21:18
Show Gist options
  • Save rafaelbernard/a6222b3aec902a60db3a81f003fa52f7 to your computer and use it in GitHub Desktop.
Save rafaelbernard/a6222b3aec902a60db3a81f003fa52f7 to your computer and use it in GitHub Desktop.
// original clone adapted from https://dev.to/samanthaming/how-to-deep-clone-an-array-in-javascript-3cig
// and the example at http://jsben.ch/q2ez1
//
// Deep clone written by @obscurerichard https://github.com/obscurerichard
const clone = (items) => items.map(item => Array.isArray(item) ? clone(item) : item);
// ✅ Nested array NOT affected
var src = [1, [2], 3];
var dest = clone(src)
// Make some changes
dest[0] = '?'; // change shallow element
dest[1][0] = '?'; // change nested element
console.log("Expect: 1, [ 2 ], 3 ]")
console.log("src", src);
console.log("Expect: [ '?', [ '?' ], 3 ]")
console.log("dest", dest);
// ❌ clone fails us here
src = [1, [{ foo: 0, bar: (baz) => baz + 2}], 2];
console.log("src", src, src[1][0].bar(2));
dest = clone(src)
dest[0] = "?"
dest[1][0].foo = "?"
dest[1][0].bar = (snafu) => `?${snafu}`;
console.log("Expect: 1, [ { foo: '?', bar: [Function] } ], 2 ] '?2'");
console.log("src", src, src[1][0].bar(2));
console.log("Expect: 1, [ { foo: 0, bar: [Function: bar] } ], 2 ] 4");
console.log("dest", dest, dest[1][0].bar(2));
console.log("*** uh-oh, clone did not work as expected. We need deepClone()");
const deepClone = (items) => Array.isArray(items) ? items.map((item) => deepClone(item)) : typeof(items) === "object" ? Object.assign({}, items) : items;
// ✅ Simple scalar NOT affected
src = 1;
dest = deepClone(src);
dest = "?"
console.log("Expect: 1");
console.log("src", src);
console.log("Expect: ?");
console.log("dest", dest);
// ✅ Simple function NOT affected
src = (snafu) => snafu + 2;
dest = deepClone(src);
dest = (fubar) => `?${fubar}`;
console.log("Expect: 4");
console.log("src", src(2));
console.log('Expect: "?2"');
console.log("dest", dest(2));
// ✅ Simple object NOT affected
src = {foo: 0, bar: 1};
dest = deepClone(src);
dest.foo = "?"
console.log("Expect: { foo: 0, bar: 1 }");
console.log("src", src);
console.log("Expect: { foo: '?', bar: 1 }");
console.log("dest", dest);
// ✅ Nested object with scalars objects and arrays NOT affected
src = [1, [{ foo: 0, bar: (fubar) => fubar + 2, baz: {}, xyzzy: [1,2] }], 2];
dest = deepClone(src);
dest[0] = "?";
dest[1][0].foo = "?";
dest[1][0].bar = (snafu) => `?${snafu}`;
dest[1][0].baz = { x: 1 }
dest[1][0].xyzzy = [2, 4]
console.log("Expect only dest to have ? and a different array and function results")
console.log("src", src, src[1][0].bar(2), src[1][0].xyzzy);
console.log("dest", dest, dest[1][0].bar(2), dest[1][0].xyzzy);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment