Skip to content

Instantly share code, notes, and snippets.

@bumfo

bumfo/deep.js Secret

Last active February 10, 2018 02:42
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 bumfo/b41088a717a0ee633fb91ce1b334b4fb to your computer and use it in GitHub Desktop.
Save bumfo/b41088a717a0ee633fb91ce1b334b4fb to your computer and use it in GitHub Desktop.
deep copy
class Stack {
constructor(initialCapacity) {
initialCapacity = initialCapacity | 0;
if (!(initialCapacity > 0)) {
initialCapacity = 1;
}
this._arr = new Array(initialCapacity);
this._n = 0;
}
push(el) {
if (this._n >= this._arr.length) {
this._arr.length *= 2;
}
this._arr[this._n] = el;
++this._n;
}
pop() {
--this._n;
}
top() {
return this._arr[this._n - 1];
}
empty() {
return !(this._n > 0);
}
}
class CopyTask {
constructor(parent, parentKey, obj) {
this.parent = parent;
this.parentKey = parentKey;
this.obj = obj;
}
}
function skeletonClone(obj) {
if (Array.isArray(obj)) {
return new Array(obj.length);
} else {
return Object.create(Object.getPrototypeOf(obj));
}
}
function deepClone(root) {
var stack = new Stack();
var container = {};
stack.push(new CopyTask(container, 'copied', root));
while (!stack.empty()) {
var task = stack.top();
stack.pop();
var obj = task.obj;
var copied = skeletonClone(obj);
task.parent[task.parentKey] = copied;
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
var child = obj[key];
if (child != null) {
switch (typeof child) {
case 'string':
case 'number':
case 'boolean':
case 'symbol':
case 'undefined':
copied[key] = child;
break;
default:
stack.push(new CopyTask(copied, key, obj[key]));
}
} else {
copied[key] = null;
}
}
}
return container.copied;
}
var arr = ['c', 'd', 'e'];
arr.hello = 123;
var test = {
'hello': {
'a': 0,
'b': {},
},
[1]: 'b',
'world': arr,
};
var copied = deepClone(test);
console.log('original:', test);
console.log('copied:', copied);
arr[0] = 'I am changed';
console.log('\nMutating original\n')
console.log('original:', test);
console.log('copied:', copied);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment