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. (see Revision 3 by Corban Brook)
Revision 22: added LoDash since someone brought Underscore, using CDN for UnderScore
Preparation code
<script src="http://code.jquery.com/jquery-1.5.1.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"></script>
<script>var underscore = _.noConflict();</script>
<script src="https://raw.github.com/bestiejs/lodash/master/lodash.min.js"></script>
<script>var lodash = _.noConflict();</script>
<script>
//allow UnderScore vs LoDash
var lodash = window.lodash,
underscore = window.underscore;
//continue test setup
var oldObject = {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
f: function() {
return 6;
},
g: [7, 8, 9]
};
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = obj[i];
}
}
return target;
}
function clone_deep(obj) {
var target = {};
for (var i in obj) {
if (typeof(obj) === 'object') {
target[i] = clone_deep(obj[i]);
}
else {
target[i] = obj[i];
}
}
return target;
}
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… |
slice(0) |
|
pending… |
underscore.clone |
|
pending… |
lodash.clone |
|
pending… |
clone_deep |
|
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
1 comment
Most of these that claim to do deep cloning don't actually do valid deep cloning. This is a typical case where this jsperf doesn't tell you anything useful since it test apples, oranges, and bananas against each other. OBVIOUSLY shallow clone (if acceptable) is faster than deep clone. This test SHOULD only do one or the other.
To fix that, I put up this jsperf, which tests ONLY deep clone (and shows where 2 of them fail):
http://jsperf.com/deep-cloning-of-objects