Cloning an Object
JavaScript performance comparison
Info
There is no quick and easy facility for cloning an object, Some people recommend using JQuery.extend others JSON.parse/stringify
http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object
If you want the fastest possible clone function. I would personally anticipate the data structure of your object and write a custom clone to handle it.
Preparation code
<script src="http://code.jquery.com/jquery-1.5.1.js" type="text/javascript"></script>
<script>
var oldObject = {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
f: function() {
return 6;
},
g: [7, 8, 9]
};
var i = 1000;
while (i--)
oldObject[Math.random()] = i;
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
}
return target;
}
var extend = function(source, target) {
var keys = Object.keys(source),
i = keys.length,
target = target || {};
while (i--) {
target[keys[i]] = source[keys[i]];
}
return target;
}
var fork = function(source) {
var
objmap = new Map(),
targetOut = {__proto__: source.__proto__},
target,
stack = {0: {source: source, target: targetOut}},
sp = 0,
ss = 1,
keys, key, j, scope, tmp;
while ((scope = stack[sp++])) {
keys = Object.keys(scope.source);
j = keys.length;
while (j--) {
source = scope.source[key = keys[j]];
if (source !== null && source === Object(source)) {
if ((tmp = objmap.get(source))) {
scope.target[key] = tmp;
} else {
scope.target[key] = target = {__proto__: source.__proto__};
stack[ss++] = {source: source, target: target};
objmap.set(source, target);
}
} else {
scope.target[key] = source;
}
}
delete stack[sp - 1];
}
target = source = stack = keys = key = scope = null;
return targetOut;
};
Object.defineProperties(Object, {
'extend': {
'configurable': true,
'enumerable': false,
'value': function extend(what, wit) {
var extObj, witKeys = Object.keys(wit);
extObj = Object.keys(what).length ? Object.clone(what) : {};
witKeys.forEach(function(key) {
Object.defineProperty(extObj, key, Object.getOwnPropertyDescriptor(wit, key));
});
return extObj;
},
'writable': true
},
'clone': {
'configurable': true,
'enumerable': false,
'value': function clone(obj) {
return Object.extend({}, obj);
},
'writable': true
}
});
</script>
Preparation code output
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
JQuery.extend deep |
|
pending… |
JSON |
|
pending… |
JQuery.extend |
|
pending… |
simple clone function |
|
pending… |
ES5 Object.clone |
|
pending… |
efficient deep clone |
|
pending… |
efficient extend |
|
pending… |
Compare results of other browsers
Revisions
You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:
- Revision 1: published by Corban Brook
- Revision 2: published by Corban Brook
- Revision 3: published by Corban Brook
- Revision 4: published by siR
- Revision 6: published and last updated
- Revision 7: published
- Revision 8: published
- Revision 9: published
- Revision 10: published
- Revision 11: published
- Revision 12: published
- Revision 13: published by Matteo Mirk
- Revision 14: published by Derek
- Revision 15: published and last updated
- Revision 16: published
- Revision 17: published by Felix
- Revision 18: published
- Revision 19: published and last updated
- Revision 20: published
- Revision 21: published by @murger
- Revision 22: published by tomByrer
- Revision 23: published by Jesper Petersson
- Revision 24: published by check if all arrays are empty
- Revision 25: published
- Revision 26: published
- Revision 27: published by collibra
- Revision 28: published by A. Matías Quezada
- Revision 32: published by Abdullah
- Revision 34: published
- Revision 36: published
- Revision 40: published
- Revision 41: published
- Revision 42: published
- Revision 43: published by Jonathan Perry
- Revision 44: published by Jonathan Perry
- Revision 45: published
- Revision 46: published by Alex Rodin
- Revision 48: published by cezary
- Revision 49: published
- Revision 50: published
- Revision 52: published
- Revision 53: published
- Revision 54: published
- Revision 55: published
- Revision 56: published
- Revision 57: published
- Revision 58: published
- Revision 60: published by Stefano Sergio
- Revision 61: published by cfstras
- Revision 62: published
- Revision 63: published
- Revision 65: published by Jeremy Banks
- Revision 66: published
0 comments