Created
July 18, 2013 23:34
-
-
Save valueof/6033987 to your computer and use it in GitHub Desktop.
Which approach to cloning objects is faster? (Assuming there are no circular references, get/set, etc.)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Candidate 1 | |
JSON.parse(JSON.stringify(obj)); | |
// Candidate 2 | |
var desc = {}; | |
Object.keys(obj).forEach(function(key) { | |
desc[key] = Object.getOwnPropertyDescriptor(obj, key); | |
}); | |
Object.create(Object.prototype, desc); |
As @simevidas said: candidate 1 discards all non-JSON values.
For candidate 2, I’d use Object.getOwnPropertyNames()
instead of Object.keys()
. As @getify mentioned, you’ll have problems whenever a property contains a mutable value (such as an array). If you are working with your own objects, a different technique may be better. For example: a copy constructor, a constructor that initializes the current instance via another instance. Lastly, line 9 should be:
Object.create(Object.getPrototypeOf(obj), desc);
If you are after speed, the following variation of candidate 2 may be faster (maybe with a normal for
loop instead of foreach
):
var clone = Object.create(Object.getPrototypeOf(obj));
Object.getOwnPropertyNames(obj).forEach(function (key) {
Object.defineProperty(clone, key, Object.getOwnPropertyDescriptor(obj, key));
});
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Methods/functions are not clonable by any reliable means, especially since you couldn't re-create the closure they'd have, so that's a non-point.
Do developers mean by "object clone" that they want a deep clone? Maybe. Maybe not. But deep cloning is deeply troublesome. Setting aside functions, what do you do about self-references or circular references? What about non-clonable objects like special built-in host objects,
window
, DOM elements, etc? I think Object deep cloning is undefinable. Object shallow cloning (copying primitives, preserving references) is somewhat less troublesome, but still has issues with circular references and self-references.OTOH, JSON cloning is quite well defined. So, I personally just punt on the whole "object cloning" thing, and only do JSON cloning. I just make it into a
JSON.clone()
"hopefill":