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
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.
Edit:
* added more value types to clone
* added internal and self references to the object to clone.
* added tests for major libs providing a clone() function
Preparation code
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js">
</script>
<script src="http://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js">
</script>
<script src="http://yui.yahooapis.com/combo?3.5.0/build/yui-base/yui-base-min.js&3.5.0/build/oop/oop-min.js">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js">
</script>
<script src="http://cdn.sencha.io/ext-4.0.7-gpl/ext-all.js">
</script>
<script src="http://oranlooney.com/static/javascript/deepCopy.js"></script>
<script>
var oldObject = {
a: 1,
b: "str",
c: true,
d: false,
e: null,
f: function() {
return 6;
},
g: [7, 8, 9],
h: new Date(),
i: {
a: new Date()
},
f: /asd/i,
u: undefined
};
// references
oldObject.ref = oldObject.g;
oldObject.i.deep_ref = oldObject.f;
// cyclic reference
oldObject.self = oldObject;
function clone(obj) {
var target = {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
target[i] = clone(obj[i]);
}
}
return target;
}
function clone2(o, b) {
var a;
if (Date.isInstanceOfType(o)) {
return new Date((o).getTime());
} else if (Array.isInstanceOfType(o)) {
a = [];
} else if (Function.isInstanceOfType(o)) {
return o;
} else if (Object.isInstanceOfType(o)) {
a = {};
} else {
return o;
}
for (var i in o) {
if (b || o.hasOwnProperty(i)) {
a[i] = clone2(o[i]);
}
}
return a;
}
function cloneJsonObject(o) {
// similar to clone2, but assuming o came from a JSON string, so we can skip hasOwnProperty checks
var a;
if (Date.isInstanceOfType(o)) {
return new Date((o).getTime());
} else if (Array.isInstanceOfType(o)) {
a = [];
} else if (Function.isInstanceOfType(o)) {
return o;
} else if (Object.isInstanceOfType(o)) {
a = {};
} else {
return o;
}
for (var i in o) {
a[i] = cloneJsonObject(o[i]);
}
return a;
}
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
}
});
//setup YUI module
Y = YUI().use('oop');
</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… |
simple clone function |
|
pending… |
ES5 Object.clone |
|
pending… |
MSAjax |
|
pending… |
Properly clone dates |
|
pending… |
cloneJsonObject |
|
pending… |
undescore clone |
|
pending… |
YUI clone |
|
pending… |
Dojo clone |
|
pending… |
ExtJS 4 clone |
|
pending… |
OWL deep copy |
|
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