Skip to content

Instantly share code, notes, and snippets.

@je-so
Last active October 10, 2018 07:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save je-so/3b49bbd1f0cb547358fd1a097e90fb31 to your computer and use it in GitHub Desktop.
Save je-so/3b49bbd1f0cb547358fd1a097e90fb31 to your computer and use it in GitHub Desktop.
deep copy of javascript object (version ES6)
//
// Precondition: 1. "obj is not allowed to contain references pointing to itself"
// (function calls itself recursively, so this precondition
// must be matched by all contained objects)
//
function deepCopy(obj)
{
if (typeof obj !== 'object' || obj === null)
return obj
const newObject = (obj.constructor === Array ? [] : {})
const keys = Object.keys(obj)
for (const i in keys) {
newObject[keys[i]] = deepCopy(obj[keys[i]])
}
return newObject
}
const o1 = {
a: null,
b: 1,
c: 'string',
d: [ 1, 2, 3, { 4: null } ],
e: {
shared_value: 'deep copy',
},
}
// test shallow vs. deep copy
const o1_shallow_copy = Object.assign({},o1)
const o1_deep_copy = deepCopy(o1)
o1.e.shared_value = 'shallow copy'
console.log("o1_shallow_copy: ", o1_shallow_copy)
console.log("o1_deep_copy: ", o1_deep_copy)
//
// Supports objects with self references
//
function deepCopy(obj)
{
const self_refs = new Map()
function deepCopySafe(obj)
{
if (typeof obj !== 'object' || obj === null)
return obj
if (self_refs.has(obj))
return self_refs.get(obj)
const newObject = (obj.constructor === Array ? [] : {})
self_refs.set(obj, newObject)
const keys = Object.keys(obj)
for (const i in keys) {
newObject[keys[i]] = deepCopySafe(obj[keys[i]])
}
return newObject
}
return deepCopySafe(obj)
}
// test circular linked list
const o2 = {
value: 2,
next: null,
}
const o3 = {
value: 3,
next: o2,
}
o2.next = o3
const o4 = deepCopy(o2)
console.log("linked list:", o2)
console.log("deep copy of linked list:", o4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment