How do I correctly clone a JavaScript object?












2703















I have an object, x. I'd like to copy it as object y, such that changes to y do not modify x. I realized that copying objects derived from built-in JavaScript objects will result in extra, unwanted properties. This isn't a problem, since I'm copying one of my own, literal-constructed objects.



How do I correctly clone a JavaScript object?










share|improve this question




















  • 28





    See this question: stackoverflow.com/questions/122102/…

    – Niyaz
    Jun 21 '11 at 10:13






  • 222





    For JSON, I use mObj=JSON.parse(JSON.stringify(jsonObject));

    – Lord Loh.
    Feb 2 '13 at 10:09






  • 57





    I really don't get why no one suggests Object.create(o), it does everything the author asks?

    – froginvasion
    Aug 8 '14 at 15:23






  • 29





    var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; After doing this, y.deep.key will also be 2, hence Object.create CAN NOT BE USED for cloning...

    – Ruben Stolk
    Jul 4 '15 at 15:04








  • 15





    @r3wt that will not work... Please post only after doing basic test of the solution..

    – akshay
    Feb 16 '16 at 18:54
















2703















I have an object, x. I'd like to copy it as object y, such that changes to y do not modify x. I realized that copying objects derived from built-in JavaScript objects will result in extra, unwanted properties. This isn't a problem, since I'm copying one of my own, literal-constructed objects.



How do I correctly clone a JavaScript object?










share|improve this question




















  • 28





    See this question: stackoverflow.com/questions/122102/…

    – Niyaz
    Jun 21 '11 at 10:13






  • 222





    For JSON, I use mObj=JSON.parse(JSON.stringify(jsonObject));

    – Lord Loh.
    Feb 2 '13 at 10:09






  • 57





    I really don't get why no one suggests Object.create(o), it does everything the author asks?

    – froginvasion
    Aug 8 '14 at 15:23






  • 29





    var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; After doing this, y.deep.key will also be 2, hence Object.create CAN NOT BE USED for cloning...

    – Ruben Stolk
    Jul 4 '15 at 15:04








  • 15





    @r3wt that will not work... Please post only after doing basic test of the solution..

    – akshay
    Feb 16 '16 at 18:54














2703












2703








2703


749






I have an object, x. I'd like to copy it as object y, such that changes to y do not modify x. I realized that copying objects derived from built-in JavaScript objects will result in extra, unwanted properties. This isn't a problem, since I'm copying one of my own, literal-constructed objects.



How do I correctly clone a JavaScript object?










share|improve this question
















I have an object, x. I'd like to copy it as object y, such that changes to y do not modify x. I realized that copying objects derived from built-in JavaScript objects will result in extra, unwanted properties. This isn't a problem, since I'm copying one of my own, literal-constructed objects.



How do I correctly clone a JavaScript object?







javascript clone javascript-objects






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 5 '18 at 0:09


























community wiki





14 revs, 9 users 30%
mindeavor









  • 28





    See this question: stackoverflow.com/questions/122102/…

    – Niyaz
    Jun 21 '11 at 10:13






  • 222





    For JSON, I use mObj=JSON.parse(JSON.stringify(jsonObject));

    – Lord Loh.
    Feb 2 '13 at 10:09






  • 57





    I really don't get why no one suggests Object.create(o), it does everything the author asks?

    – froginvasion
    Aug 8 '14 at 15:23






  • 29





    var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; After doing this, y.deep.key will also be 2, hence Object.create CAN NOT BE USED for cloning...

    – Ruben Stolk
    Jul 4 '15 at 15:04








  • 15





    @r3wt that will not work... Please post only after doing basic test of the solution..

    – akshay
    Feb 16 '16 at 18:54














  • 28





    See this question: stackoverflow.com/questions/122102/…

    – Niyaz
    Jun 21 '11 at 10:13






  • 222





    For JSON, I use mObj=JSON.parse(JSON.stringify(jsonObject));

    – Lord Loh.
    Feb 2 '13 at 10:09






  • 57





    I really don't get why no one suggests Object.create(o), it does everything the author asks?

    – froginvasion
    Aug 8 '14 at 15:23






  • 29





    var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; After doing this, y.deep.key will also be 2, hence Object.create CAN NOT BE USED for cloning...

    – Ruben Stolk
    Jul 4 '15 at 15:04








  • 15





    @r3wt that will not work... Please post only after doing basic test of the solution..

    – akshay
    Feb 16 '16 at 18:54








28




28





See this question: stackoverflow.com/questions/122102/…

– Niyaz
Jun 21 '11 at 10:13





See this question: stackoverflow.com/questions/122102/…

– Niyaz
Jun 21 '11 at 10:13




222




222





For JSON, I use mObj=JSON.parse(JSON.stringify(jsonObject));

– Lord Loh.
Feb 2 '13 at 10:09





For JSON, I use mObj=JSON.parse(JSON.stringify(jsonObject));

– Lord Loh.
Feb 2 '13 at 10:09




57




57





I really don't get why no one suggests Object.create(o), it does everything the author asks?

– froginvasion
Aug 8 '14 at 15:23





I really don't get why no one suggests Object.create(o), it does everything the author asks?

– froginvasion
Aug 8 '14 at 15:23




29




29





var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; After doing this, y.deep.key will also be 2, hence Object.create CAN NOT BE USED for cloning...

– Ruben Stolk
Jul 4 '15 at 15:04







var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; After doing this, y.deep.key will also be 2, hence Object.create CAN NOT BE USED for cloning...

– Ruben Stolk
Jul 4 '15 at 15:04






15




15





@r3wt that will not work... Please post only after doing basic test of the solution..

– akshay
Feb 16 '16 at 18:54





@r3wt that will not work... Please post only after doing basic test of the solution..

– akshay
Feb 16 '16 at 18:54












60 Answers
60






active

oldest

votes













1 2
next












1416














To do this for any object in JavaScript will not be simple or straightforward. You will run into the problem of erroneously picking up attributes from the object's prototype that should be left in the prototype and not copied to the new instance. If, for instance, you are adding a clone method to Object.prototype, as some answers depict, you will need to explicitly skip that attribute. But what if there are other additional methods added to Object.prototype, or other intermediate prototypes, that you don't know about? In that case, you will copy attributes you shouldn't, so you need to detect unforeseen, non-local attributes with the hasOwnProperty method.



In addition to non-enumerable attributes, you'll encounter a tougher problem when you try to copy objects that have hidden properties. For example, prototype is a hidden property of a function. Also, an object's prototype is referenced with the attribute __proto__, which is also hidden, and will not be copied by a for/in loop iterating over the source object's attributes. I think __proto__ might be specific to Firefox's JavaScript interpreter and it may be something different in other browsers, but you get the picture. Not everything is enumerable. You can copy a hidden attribute if you know its name, but I don't know of any way to discover it automatically.



Yet another snag in the quest for an elegant solution is the problem of setting up the prototype inheritance correctly. If your source object's prototype is Object, then simply creating a new general object with {} will work, but if the source's prototype is some descendant of Object, then you are going to be missing the additional members from that prototype which you skipped using the hasOwnProperty filter, or which were in the prototype, but weren't enumerable in the first place. One solution might be to call the source object's constructor property to get the initial copy object and then copy over the attributes, but then you still will not get non-enumerable attributes. For example, a Date object stores its data as a hidden member:



function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}

var d1 = new Date();

/* Executes function after 5 seconds. */
setTimeout(function(){
var d2 = clone(d1);
alert("d1 = " + d1.toString() + "nd2 = " + d2.toString());
}, 5000);


The date string for d1 will be 5 seconds behind that of d2. A way to make one Date the same as another is by calling the setTime method, but that is specific to the Date class. I don't think there is a bullet-proof general solution to this problem, though I would be happy to be wrong!



When I had to implement general deep copying I ended up compromising by assuming that I would only need to copy a plain Object, Array, Date, String, Number, or Boolean. The last 3 types are immutable, so I could perform a shallow copy and not worry about it changing. I further assumed that any elements contained in Object or Array would also be one of the 6 simple types in that list. This can be accomplished with code like the following:



function clone(obj) {
var copy;

// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;

// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}

// Handle Array
if (obj instanceof Array) {
copy = ;
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = clone(obj[i]);
}
return copy;
}

// Handle Object
if (obj instanceof Object) {
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
}
return copy;
}

throw new Error("Unable to copy obj! Its type isn't supported.");
}


The above function will work adequately for the 6 simple types I mentioned, as long as the data in the objects and arrays form a tree structure. That is, there isn't more than one reference to the same data in the object. For example:



// This would be cloneable:
var tree = {
"left" : { "left" : null, "right" : null, "data" : 3 },
"right" : null,
"data" : 8
};

// This would kind-of work, but you would get 2 copies of the
// inner node instead of 2 references to the same copy
var directedAcylicGraph = {
"left" : { "left" : null, "right" : null, "data" : 3 },
"data" : 8
};
directedAcyclicGraph["right"] = directedAcyclicGraph["left"];

// Cloning this would cause a stack overflow due to infinite recursion:
var cyclicGraph = {
"left" : { "left" : null, "right" : null, "data" : 3 },
"data" : 8
};
cyclicGraph["right"] = cyclicGraph;


It will not be able to handle any JavaScript object, but it may be sufficient for many purposes as long as you don't assume that it will just work for anything you throw at it.






share|improve this answer





















  • 5





    almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

    – Trindaz
    Mar 28 '12 at 0:08








  • 5





    For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

    – Trindaz
    Mar 29 '12 at 6:48






  • 5





    Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

    – KooiInc
    May 20 '12 at 7:42






  • 5





    In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

    – cyon
    Nov 29 '14 at 3:29






  • 4





    Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

    – 1owk3y
    Nov 30 '17 at 23:12





















832














If you do not use functions within your object, a very simple one liner can be the following:



var cloneOfA = JSON.parse(JSON.stringify(a));


This works for all kind of objects containing objects, arrays, strings, booleans and numbers.



See also this article about the structured clone algorithm of browsers which is used when posting messages to and from a worker. It also contains a function for deep cloning.






share|improve this answer





















  • 39





    Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

    – Nux
    Aug 12 '13 at 18:56








  • 66





    @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

    – BeauCielBleu
    May 14 '14 at 15:27








  • 12





    I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

    – mirhagk
    Oct 7 '14 at 21:08






  • 29





    It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

    – kumar_harsh
    Oct 8 '14 at 8:42






  • 11





    2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

    – James Foster
    Feb 10 '16 at 12:15





















747














With jQuery, you can shallow copy with extend:



var copiedObject = jQuery.extend({}, originalObject)


subsequent changes to the copiedObject will not affect the originalObject, and vice versa.



Or to make a deep copy:



var copiedObject = jQuery.extend(true, {}, originalObject)





share|improve this answer





















  • 163





    or even: var copiedObject = jQuery.extend({},originalObject);

    – Grant McLean
    May 8 '11 at 2:11






  • 81





    Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

    – Will Shaver
    Jun 21 '11 at 0:19








  • 6





    Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

    – Garry English
    Nov 16 '11 at 16:31






  • 3





    @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

    – thorinkor
    Oct 17 '13 at 8:41






  • 3





    Just a note, this doesn't copy the proto constructor of the original object

    – Sam Jones
    May 30 '14 at 15:20



















583














In ECMAScript 6 there is Object.assign method, which copies values of all enumerable own properties from one object to another. For example:



var x = {myProp: "value"};
var y = Object.assign({}, x);


But be aware that nested objects are still copied as reference.






share|improve this answer


























  • Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

    – user339827
    Feb 11 '16 at 0:52






  • 211





    But be aware that this makes a shallow copy only. Nested objects are still copied as references!

    – ohager
    Mar 28 '16 at 12:30






  • 18





    Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

    – Marcus Junius Brutus
    Mar 29 '16 at 15:09








  • 14





    I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

    – Saulius
    May 29 '16 at 15:09






  • 1





    This is the same as @EugeneTiurin his answer.

    – Wilt
    Jun 9 '16 at 10:07



















164














Per MDN:




  • If you want shallow copy, use Object.assign({}, a)

  • For "deep" copy, use JSON.parse(JSON.stringify(a))


There is no need for external libraries but you need to check browser compatibility first.






share|improve this answer





















  • 6





    JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

    – Edza
    Apr 5 '17 at 9:54






  • 3





    JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

    – Steve Seeger
    Apr 12 '18 at 20:34











  • for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

    – Tareq
    Apr 12 '18 at 21:34











  • works like a charm!

    – Bilal Ahmad
    Aug 16 '18 at 14:26











  • This is good but take care if the object has functions inside

    – Zloy Smiertniy
    Mar 14 at 12:32



















128














There are many answers, but none that mentions Object.create from ECMAScript 5, which admittedly does not give you an exact copy, but sets the source as the prototype of the new object.



Thus, this is not an exact answer to the question, but it is a one-line solution and thus elegant. And it works best for 2 cases:




  1. Where such inheritance is useful (duh!)

  2. Where the source object won't be modified, thus making the relation between the 2 objects a non issue.


Example:



var foo = { a : 1 };
var bar = Object.create(foo);
foo.a; // 1
bar.a; // 1
foo.a = 2;
bar.a; // 2 - prototype changed
bar.a = 3;
foo.a; // Still 2, since setting bar.a makes it an "own" property


Why do I consider this solution to be superior? It's native, thus no looping, no recursion. However, older browsers will need a polyfill.






share|improve this answer


























  • Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

    – zamnuts
    Apr 29 '13 at 8:07






  • 91





    This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

    – d13
    Jan 16 '14 at 16:18






  • 7





    I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

    – froginvasion
    Aug 8 '14 at 15:26






  • 4





    @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

    – d13
    Dec 2 '14 at 14:08






  • 1





    This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

    – prajnavantha
    Jun 11 '17 at 8:28



















112














An elegant way to clone a Javascript object in one line of code



An Object.assign method is part of the ECMAScript 2015 (ES6) standard and does exactly what you need.



var clone = Object.assign({}, obj);



The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.




Read more...



The polyfill to support older browsers:



if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
enumerable: false,
configurable: true,
writable: true,
value: function(target) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert first argument to object');
}

var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) {
continue;
}
nextSource = Object(nextSource);

var keysArray = Object.keys(nextSource);
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}





share|improve this answer


























  • Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

    – Qwertie
    May 31 '16 at 23:14











  • @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

    – Eugene Tiurin
    Jun 2 '16 at 10:56











  • Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

    – Qwertie
    Jun 3 '16 at 15:20






  • 32





    this will only perform a shallow "cloning"

    – Marcus Junius Brutus
    Jul 25 '16 at 13:27













  • This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

    – Zloy Smiertniy
    Mar 14 at 12:36



















75














If you're okay with a shallow copy, the underscore.js library has a clone method.



y = _.clone(x);


or you can extend it like



copiedObject = _.extend({},originalObject);





share|improve this answer





















  • 36





    And lodash has a cloneDeep

    – dule
    Jun 4 '13 at 0:11






  • 2





    Thanks. Using this technique on a Meteor server.

    – Turbo
    Apr 1 '15 at 4:30











  • Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

    – Arnaud Bouchot
    May 16 '18 at 10:08



















74














There are several issues with most solutions on the internet. So I decided to make a follow-up, which includes, why the accepted answer shouldn't be accepted.



starting situation



I want to deep-copy a Javascript Object with all of its children and their children and so on. But since I'm not kind of a normal developer, my Object has normal properties, circular structures and even nested objects.



So let's create a circular structure and a nested object first.



function Circ() {
this.me = this;
}

function Nested(y) {
this.y = y;
}


Let's bring everything together in an Object named a.



var a = {
x: 'a',
circ: new Circ(),
nested: new Nested('a')
};


Next, we want to copy a into a variable named b and mutate it.



var b = a;

b.x = 'b';
b.nested.y = 'b';


You know what happened here because if not you wouldn't even land on this great question.



console.log(a, b);

a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}

b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}


Now let's find a solution.



JSON



The first attempt I tried was using JSON.



var b = JSON.parse( JSON.stringify( a ) );

b.x = 'b';
b.nested.y = 'b';


Don't waste too much time on it, you'll get TypeError: Converting circular structure to JSON.



Recursive copy (the accepted "answer")



Let's have a look at the accepted answer.



function cloneSO(obj) {
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;

// Handle Date
if (obj instanceof Date) {
var copy = new Date();
copy.setTime(obj.getTime());
return copy;
}

// Handle Array
if (obj instanceof Array) {
var copy = ;
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = cloneSO(obj[i]);
}
return copy;
}

// Handle Object
if (obj instanceof Object) {
var copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
}
return copy;
}

throw new Error("Unable to copy obj! Its type isn't supported.");
}


Looks good, heh? It's a recursive copy of the object and handles other types as well, like Date, but that wasn't a requirement.



var b = cloneSO(a);

b.x = 'b';
b.nested.y = 'b';


Recursion and circular structures doesn't work well together... RangeError: Maximum call stack size exceeded



native solution



After arguing with my co-worker, my boss asked us what happened, and he found a simple solution after some googling. It's called Object.create.



var b = Object.create(a);

b.x = 'b';
b.nested.y = 'b';


This solution was added to Javascript some time ago and even handles circular structure.



console.log(a, b);

a --> Object {
x: "a",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}

b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}


... and you see, it didn't work with the nested structure inside.



polyfill for the native solution



There's a polyfill for Object.create in the older browser just like the IE 8. It's something like recommended by Mozilla, and of course, it's not perfect and results in the same problem as the native solution.



function F() {};
function clonePF(o) {
F.prototype = o;
return new F();
}

var b = clonePF(a);

b.x = 'b';
b.nested.y = 'b';


I've put F outside the scope so we can have a look at what instanceof tells us.



console.log(a, b);

a --> Object {
x: "a",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}

b --> F {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}

console.log(typeof a, typeof b);

a --> object
b --> object

console.log(a instanceof Object, b instanceof Object);

a --> true
b --> true

console.log(a instanceof F, b instanceof F);

a --> false
b --> true


Same problem as the native solution, but a little bit worse output.



the better (but not perfect) solution



When digging around, I found a similar question (In Javascript, when performing a deep copy, how do I avoid a cycle, due to a property being "this"?) to this one, but with a way better solution.



function cloneDR(o) {
const gdcc = "__getDeepCircularCopy__";
if (o !== Object(o)) {
return o; // primitive value
}

var set = gdcc in o,
cache = o[gdcc],
result;
if (set && typeof cache == "function") {
return cache();
}
// else
o[gdcc] = function() { return result; }; // overwrite
if (o instanceof Array) {
result = ;
for (var i=0; i<o.length; i++) {
result[i] = cloneDR(o[i]);
}
} else {
result = {};
for (var prop in o)
if (prop != gdcc)
result[prop] = cloneDR(o[prop]);
else if (set)
result[prop] = cloneDR(cache);
}
if (set) {
o[gdcc] = cache; // reset
} else {
delete o[gdcc]; // unset again
}
return result;
}

var b = cloneDR(a);

b.x = 'b';
b.nested.y = 'b';


And let's have a look at the output...



console.log(a, b);

a --> Object {
x: "a",
circ: Object {
me: Object { ... }
},
nested: Object {
y: "a"
}
}

b --> Object {
x: "b",
circ: Object {
me: Object { ... }
},
nested: Object {
y: "b"
}
}

console.log(typeof a, typeof b);

a --> object
b --> object

console.log(a instanceof Object, b instanceof Object);

a --> true
b --> true

console.log(a instanceof F, b instanceof F);

a --> false
b --> false


The requirements are matched, but there are still some smaller issues, including changing the instance of nested and circ to Object.




The structure of trees that share a leaf won't be copied, they will become two independent leaves:




        [Object]                     [Object]
/ /
/ /
|/_ _| |/_ _|
[Object] [Object] ===> [Object] [Object]
/ | |
/ | |
_| |/_ |/ |/
[Object] [Object] [Object]


conclusion



The last solution using recursion and a cache, may not be the best, but it's a real deep-copy of the object. It handles simple properties, circular structures and nested object, but it will mess up the instance of them while cloning.



jsfiddle






share|improve this answer





















  • 7





    so the conlcusion is to avoid that problem :)

    – mikus
    Oct 23 '14 at 11:39






  • 2





    An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

    – Amir Mog
    Aug 16 '16 at 16:53








  • 2





    It is shame that JS not includes native clone function.

    – l00k
    Nov 14 '16 at 14:53






  • 1





    Among all the top answers, I feel this is close to the correct one.

    – KTU
    May 15 '17 at 4:24






  • 2





    The best answer here! Hats off to you good sir!

    – Goran
    Aug 23 '18 at 12:14





















38














One particularly inelegant solution is to use JSON encoding to make deep copies of objects that do not have member methods. The methodology is to JSON encode your target object, then by decoding it, you get the copy you are looking for. You can decode as many times as you want to make as many copies as you need.



Of course, functions do not belong in JSON, so this only works for objects without member methods.



This methodology was perfect for my use case, since I'm storing JSON blobs in a key-value store, and when they are exposed as objects in a JavaScript API, each object actually contains a copy of the original state of the object so we can calculate the delta after the caller has mutated the exposed object.



var object1 = {key:"value"};
var object2 = object1;

object2 = JSON.stringify(object1);
object2 = JSON.parse(object2);

object2.key = "a change";
console.log(object1);// returns value





share|improve this answer


























  • Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

    – the_drow
    Oct 29 '09 at 20:37






  • 4





    Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

    – Kris Walker
    Oct 30 '09 at 10:27






  • 1





    IMHO the best answer, because the OP states "literal-constructed" objects

    – mark
    Oct 4 '11 at 11:35






  • 30





    There's nothing more inelegant than the use of the word unelegant.

    – Kevin Laity
    Jan 26 '12 at 20:18






  • 1





    @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

    – abarnert
    Aug 14 '12 at 1:58



















31














You can simply use a spread property to copy an object without references. But be careful (see comments), the 'copy' is just on the lowest object/array level. Nested properties are still references!





Complete clone:



let x = {a: 'value1'}
let x2 = {...x}

// => mutate without references:

x2.a = 'value2'
console.log(x.a) // => 'value1'


Clone with references on second level:



const y = {a: {b: 'value3'}}
const y2 = {...y}

// => nested object is still a references:

y2.a.b = 'value4'
console.log(y.a.b) // => 'value4'




JavaScript actually does not support deep clones natively. Use an utility function. For example Ramda:




http://ramdajs.com/docs/#clone







share|improve this answer





















  • 1





    This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

    – Kamil Kiełczewski
    Apr 14 '16 at 8:23








  • 3





    This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

    – Bugs Bunny
    May 17 '16 at 13:01











  • A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

    – Cristian Traìna
    Aug 13 '18 at 17:37



















31














OK, imagine you have this object below and you want to clone it:



let obj = {a:1, b:2, c:3}; //ES6


or



var obj = {a:1, b:2, c:3}; //ES5


the answer is mainly depeneds on which ECMAscript you using, in ES6+, you can simply use Object.assign to do the clone:



let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};


or using spread operator like this:



let cloned = {...obj}; //new {a:1, b:2, c:3};


But if you using ES5, you can use few methods, but the JSON.stringify, just make sure you not using for a big chunk of data to copy, but it could be one line handy way in many cases, something like this:



let cloned = JSON.parse(JSON.stringify(obj)); 
//new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over





share|improve this answer


























  • Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

    – user1063287
    Sep 14 '18 at 11:04











  • I just use the spread operator (ES6)

    – Shiraz
    Mar 13 at 15:17











  • Right @Shiraz, but that only does a shallow copy...

    – Alireza
    Mar 14 at 9:56











  • Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

    – Alireza
    Mar 14 at 9:58



















23














For those using AngularJS, there is also direct method for cloning or extending of the objects in this library.



var destination = angular.copy(source);


or



angular.copy(source, destination);


More in angular.copy documentation...






share|improve this answer





















  • 1





    This is a deep copy FYI.

    – zamnuts
    Sep 19 '14 at 10:27



















21














A.Levy's answer is almost complete, here is my little contribution: there is a way how to handle recursive references, see this line



if(this[attr]==this) copy[attr] = copy;



If the object is XML DOM element, we must use cloneNode instead



if(this.cloneNode) return this.cloneNode(true);



Inspired by A.Levy's exhaustive study and Calvin's prototyping approach, I offer this solution:



Object.prototype.clone = function() {
if(this.cloneNode) return this.cloneNode(true);
var copy = this instanceof Array ? : {};
for(var attr in this) {
if(typeof this[attr] == "function" || this[attr]==null || !this[attr].clone)
copy[attr] = this[attr];
else if(this[attr]==this) copy[attr] = copy;
else copy[attr] = this[attr].clone();
}
return copy;
}

Date.prototype.clone = function() {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}

Number.prototype.clone =
Boolean.prototype.clone =
String.prototype.clone = function() {
return this;
}


See also Andy Burke's note in the answers.






share|improve this answer


























  • Does not work well with inheritance.

    – calbertts
    Jan 2 '14 at 18:52






  • 3





    Date.prototype.clone = function() {return new Date(+this)};

    – RobG
    Dec 2 '14 at 12:20



















18














Here is a function you can use.



function clone(obj) {
if(obj == null || typeof(obj) != 'object')
return obj;
var temp = new obj.constructor();
for(var key in obj)
temp[key] = clone(obj[key]);
return temp;
}





share|improve this answer





















  • 8





    This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

    – A. Levy
    Apr 8 '09 at 4:21











  • Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

    – james_womack
    Nov 1 '13 at 20:36











  • Upvoted for correctly calling the constructor using new. The accepted answer does not.

    – GetFree
    Jun 14 '15 at 6:29











  • works on node everything else ! still left reference links

    – user956584
    Jul 15 '17 at 22:38



















18














From this article: How to copy arrays and objects in Javascript by Brian Huisman:



Object.prototype.clone = function() {
var newObj = (this instanceof Array) ? : {};
for (var i in this) {
if (i == 'clone') continue;
if (this[i] && typeof this[i] == "object") {
newObj[i] = this[i].clone();
} else newObj[i] = this[i]
} return newObj;
};





share|improve this answer





















  • 4





    This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

    – A. Levy
    Apr 8 '09 at 4:17











  • Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

    – iPadDeveloper2011
    Aug 27 '12 at 23:19






  • 3





    @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

    – mikemaccana
    Sep 22 '12 at 22:09






  • 1





    @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

    – mikemaccana
    Oct 1 '12 at 10:54






  • 2





    why isn't var copiedObj = Object.create(obj); a great way as well?

    – Dan P.
    Apr 12 '14 at 20:16



















18














In ES-6 you can simply use Object.assign(...).
Ex:



let obj = {person: 'Thor Odinson'};
let clone = Object.assign({}, obj);


A good reference is here:
https://googlechrome.github.io/samples/object-assign-es6/






share|improve this answer





















  • 9





    It does not deep clone the object.

    – August
    Jun 1 '17 at 5:31











  • That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

    – HoldOffHunger
    Aug 16 '17 at 16:05











  • @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

    – collapsar
    Sep 1 '17 at 11:00











  • @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

    – HoldOffHunger
    Sep 1 '17 at 11:40













  • @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

    – collapsar
    Sep 1 '17 at 12:50



















15














In ECMAScript 2018



let objClone = { ...obj };


Be aware that nested objects are still copied as a reference.






share|improve this answer


























  • Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

    – Benny Neugebauer
    Jan 2 at 23:32



















14














You can clone an object and remove any reference from the previous one using a single line of code. Simply do:



var obj1 = { text: 'moo1' };
var obj2 = Object.create(obj1); // Creates a new clone without references

obj2.text = 'moo2'; // Only updates obj2's text property

console.log(obj1, obj2); // Outputs: obj1: {text:'moo1'}, obj2: {text:'moo2'}


For browsers / engines that do not currently support Object.create you can use this polyfill:



// Polyfill Object.create if it does not exist
if (!Object.create) {
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
}





share|improve this answer





















  • 1





    +1 Object.create(...) seems definitely the way to go.

    – René Nyffenegger
    Jun 30 '14 at 14:49











  • Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

    – froginvasion
    Aug 9 '14 at 12:30











  • Works well but what browsers does the polyfill work in?

    – Ian Lunn
    Oct 9 '14 at 13:25











  • If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

    – Quinthexadec
    Oct 17 '14 at 4:32








  • 8





    This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

    – Nick Desaulniers
    Oct 31 '14 at 21:25



















13














New answer to an old question! If you have the pleasure of having using ECMAScript 2016 (ES6) with Spread Syntax, it's easy.



keepMeTheSame = {first: "Me!", second: "You!"};
cloned = {...keepMeTheSame}


This provides a clean method for a shallow copy of an object. Making a deep copy, meaning makign a new copy of every value in every recursively nested object, requires on of the heavier solutions above.



JavaScript keeps evolving.






share|improve this answer





















  • 1





    it doesn't work when you have functions defined on objects

    – Petr Marek
    Feb 5 '17 at 22:06











  • as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

    – Oleh
    Apr 4 '17 at 8:12













  • @Oleh so use ` {... obj} instead of [...obj];`

    – manikant gautam
    Dec 5 '17 at 6:17













  • @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

    – Oleh
    Dec 6 '17 at 15:11



















10














Using Lodash:



var y = _.clone(x, true);





share|improve this answer





















  • 3





    OMG it would be insane to reinvent cloning. This is the only sane answer.

    – Dan Ross
    Sep 11 '13 at 8:48






  • 4





    I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

    – garbanzio
    Dec 18 '14 at 19:40











  • @DanRoss true that

    – Fahmi
    Apr 15 '17 at 11:29



















10














let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)


ES6 solution if you want to (shallow) clone a class instance and not just a property object.






share|improve this answer

































    9














    Interested in cloning simple objects :



    JSON.parse(JSON.stringify(json_original));



    Source : How to copy JavaScript object to new variable NOT by reference?






    share|improve this answer

































      8














      I think there is a simple and working answer. In deep copying there are two concerns:




      1. Keep properties dependent of each other.

      2. And keep the methods alive on cloned object.


      So I think one simple solution will be to first serialize and deserialize and then do an assign on it to copy functions too.



      let deepCloned = JSON.parse(JSON.stringify(source));
      let merged = Object.assign({}, source);
      Object.assign(merged, deepCloned);


      Although this question has many answers, I hope this one helps too.






      share|improve this answer


























      • Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

        – ConductedClever
        Jan 13 at 6:01






      • 1





        I'm using JSON.parse(JSON.stringify(source)). Always working.

        – Misha
        Feb 22 at 15:50











      • @Misha, this way you will miss the functions. The term 'works' has many meanings.

        – ConductedClever
        Feb 23 at 5:26











      • And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

        – ConductedClever
        Feb 23 at 5:29



















      6














      Jan Turoň's answer above is very close, and may be the best to use in a browser due to compatibility issues, but it will potentially cause some strange enumeration issues. For instance, executing:



      for ( var i in someArray ) { ... }


      Will assign the clone() method to i after iterating through the elements of the array. Here's an adaptation that avoids the enumeration and works with node.js:



      Object.defineProperty( Object.prototype, "clone", {
      value: function() {
      if ( this.cloneNode )
      {
      return this.cloneNode( true );
      }

      var copy = this instanceof Array ? : {};
      for( var attr in this )
      {
      if ( typeof this[ attr ] == "function" || this[ attr ] == null || !this[ attr ].clone )
      {
      copy[ attr ] = this[ attr ];
      }
      else if ( this[ attr ] == this )
      {
      copy[ attr ] = copy;
      }
      else
      {
      copy[ attr ] = this[ attr ].clone();
      }
      }
      return copy;
      }
      });

      Object.defineProperty( Date.prototype, "clone", {
      value: function() {
      var copy = new Date();
      copy.setTime( this.getTime() );
      return copy;
      }
      });

      Object.defineProperty( Number.prototype, "clone", { value: function() { return this; } } );
      Object.defineProperty( Boolean.prototype, "clone", { value: function() { return this; } } );
      Object.defineProperty( String.prototype, "clone", { value: function() { return this; } } );


      This avoids making the clone() method enumerable because defineProperty() defaults enumerable to false.






      share|improve this answer

































        6














        This is an adaptation of A. Levy's code to also handle the cloning of functions and multiple/cyclic references - what this means is that if two properties in the tree which is cloned are references of the same object, the cloned object tree will have these properties point to one and the same clone of the referenced object. This also solves the case of cyclic dependencies which, if left unhandled, leads to an infinite loop. The complexity of the algorithm is O(n)



        function clone(obj){
        var clonedObjectsArray = ;
        var originalObjectsArray = ; //used to remove the unique ids when finished
        var next_objid = 0;

        function objectId(obj) {
        if (obj == null) return null;
        if (obj.__obj_id == undefined){
        obj.__obj_id = next_objid++;
        originalObjectsArray[obj.__obj_id] = obj;
        }
        return obj.__obj_id;
        }

        function cloneRecursive(obj) {
        if (null == obj || typeof obj == "string" || typeof obj == "number" || typeof obj == "boolean") return obj;

        // Handle Date
        if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
        }

        // Handle Array
        if (obj instanceof Array) {
        var copy = ;
        for (var i = 0; i < obj.length; ++i) {
        copy[i] = cloneRecursive(obj[i]);
        }
        return copy;
        }

        // Handle Object
        if (obj instanceof Object) {
        if (clonedObjectsArray[objectId(obj)] != undefined)
        return clonedObjectsArray[objectId(obj)];

        var copy;
        if (obj instanceof Function)//Handle Function
        copy = function(){return obj.apply(this, arguments);};
        else
        copy = {};

        clonedObjectsArray[objectId(obj)] = copy;

        for (var attr in obj)
        if (attr != "__obj_id" && obj.hasOwnProperty(attr))
        copy[attr] = cloneRecursive(obj[attr]);

        return copy;
        }


        throw new Error("Unable to copy obj! Its type isn't supported.");
        }
        var cloneObj = cloneRecursive(obj);



        //remove the unique ids
        for (var i = 0; i < originalObjectsArray.length; i++)
        {
        delete originalObjectsArray[i].__obj_id;
        };

        return cloneObj;
        }


        Some quick tests



        var auxobj = {
        prop1 : "prop1 aux val",
        prop2 : ["prop2 item1", "prop2 item2"]
        };

        var obj = new Object();
        obj.prop1 = "prop1_value";
        obj.prop2 = [auxobj, auxobj, "some extra val", undefined];
        obj.nr = 3465;
        obj.bool = true;

        obj.f1 = function (){
        this.prop1 = "prop1 val changed by f1";
        };

        objclone = clone(obj);

        //some tests i've made
        console.log("test number, boolean and string cloning: " + (objclone.prop1 == obj.prop1 && objclone.nr == obj.nr && objclone.bool == obj.bool));

        objclone.f1();
        console.log("test function cloning 1: " + (objclone.prop1 == 'prop1 val changed by f1'));
        objclone.f1.prop = 'some prop';
        console.log("test function cloning 2: " + (obj.f1.prop == undefined));

        objclone.prop2[0].prop1 = "prop1 aux val NEW";
        console.log("test multiple references cloning 1: " + (objclone.prop2[1].prop1 == objclone.prop2[0].prop1));
        console.log("test multiple references cloning 2: " + (objclone.prop2[1].prop1 != obj.prop2[0].prop1));





        share|improve this answer





















        • 1





          As of September 2016, this is the only correct solution to the question.

          – DomQ
          Sep 27 '16 at 20:18











        • well, thanks. feel free to vote it then

          – Radu Simionescu
          Sep 28 '16 at 17:58



















        6














        function clone(src, deep) {

        var toString = Object.prototype.toString;
        if(!src && typeof src != "object"){
        //any non-object ( Boolean, String, Number ), null, undefined, NaN
        return src;
        }

        //Honor native/custom clone methods
        if(src.clone && toString.call(src.clone) == "[object Function]"){
        return src.clone(deep);
        }

        //DOM Elements
        if(src.nodeType && toString.call(src.cloneNode) == "[object Function]"){
        return src.cloneNode(deep);
        }

        //Date
        if(toString.call(src) == "[object Date]"){
        return new Date(src.getTime());
        }

        //RegExp
        if(toString.call(src) == "[object RegExp]"){
        return new RegExp(src);
        }

        //Function
        if(toString.call(src) == "[object Function]"){
        //Wrap in another method to make sure == is not true;
        //Note: Huge performance issue due to closures, comment this :)
        return (function(){
        src.apply(this, arguments);
        });

        }

        var ret, index;
        //Array
        if(toString.call(src) == "[object Array]"){
        //.slice(0) would soft clone
        ret = src.slice();
        if(deep){
        index = ret.length;
        while(index--){
        ret[index] = clone(ret[index], true);
        }
        }
        }
        //Object
        else {
        ret = src.constructor ? new src.constructor() : {};
        for (var prop in src) {
        ret[prop] = deep
        ? clone(src[prop], true)
        : src[prop];
        }
        }

        return ret;
        };





        share|improve this answer


























        • Did this solution help you ? Let me know if u see any issues.

          – user1547016
          Aug 1 '12 at 17:00






        • 2





          if(!src && typeof src != "object"){. I think that should be || not &&.

          – MikeM
          Apr 8 '13 at 9:34











        • A vote for knowing how to copy a Date in less than 3 lines of code.

          – RobG
          Dec 2 '14 at 12:32



















        6














        I've written my own implementation. Not sure if it counts as a better solution:



        /*
        a function for deep cloning objects that contains other nested objects and circular structures.
        objects are stored in a 3D array, according to their length (number of properties) and their depth in the original object.
        index (z)
        |
        |
        |
        |
        |
        | depth (x)
        |_ _ _ _ _ _ _ _ _ _ _ _
        /_/_/_/_/_/_/_/_/_/
        /_/_/_/_/_/_/_/_/_/
        /_/_/_/_/_/_/...../
        /................./
        /..... /
        / /
        /------------------
        object length (y) /
        */


        Following is the implementation:



        function deepClone(obj) {
        var depth = -1;
        var arr = ;
        return clone(obj, arr, depth);
        }

        /**
        *
        * @param obj source object
        * @param arr 3D array to store the references to objects
        * @param depth depth of the current object relative to the passed 'obj'
        * @returns {*}
        */
        function clone(obj, arr, depth){
        if (typeof obj !== "object") {
        return obj;
        }

        var length = Object.keys(obj).length; // native method to get the number of properties in 'obj'

        var result = Object.create(Object.getPrototypeOf(obj)); // inherit the prototype of the original object
        if(result instanceof Array){
        result.length = length;
        }

        depth++; // depth is increased because we entered an object here

        arr[depth] = ; // this is the x-axis, each index here is the depth
        arr[depth][length] = ; // this is the y-axis, each index is the length of the object (aka number of props)
        // start the depth at current and go down, cyclic structures won't form on depths more than the current one
        for(var x = depth; x >= 0; x--){
        // loop only if the array at this depth and length already have elements
        if(arr[x][length]){
        for(var index = 0; index < arr[x][length].length; index++){
        if(obj === arr[x][length][index]){
        return obj;
        }
        }
        }
        }

        arr[depth][length].push(obj); // store the object in the array at the current depth and length
        for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) result[prop] = clone(obj[prop], arr, depth);
        }

        return result;
        }





        share|improve this answer


























        • not working for my object, although my case is a little bit complex.

          – Sajuuk
          Jan 2 at 6:33



















        5














        I just wanted to add to all the Object.create solutions in this post, that this does not work in the desired way with nodejs.



        In Firefox the result of



        var a = {"test":"test"};
        var b = Object.create(a);
        console.log(b);´


        is



        {test:"test"}.



        In nodejs it is



        {}





        share|improve this answer


























        • No this is wrong. b.test returns test.

          – Shripad Krishna
          Oct 16 '13 at 20:15











        • This is prototypal inheritance, not cloning.

          – d13
          Jan 16 '14 at 16:15






        • 1





          @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

          – froginvasion
          Aug 8 '14 at 15:28











        • @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

          – d13
          Aug 8 '14 at 18:28











        • @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

          – froginvasion
          Aug 9 '14 at 10:13



















        5














        Since mindeavor stated that the object to be cloned is a 'literal-constructed' object, a solution might be to simply generate the object multiple times rather than cloning an instance of the object:



        function createMyObject()
        {
        var myObject =
        {
        ...
        };
        return myObject;
        }

        var myObjectInstance1 = createMyObject();
        var myObjectInstance2 = createMyObject();





        share|improve this answer





























          1 2
          next


          protected by acdcjunior Apr 5 '14 at 12:41



          Thank you for your interest in this question.
          Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



          Would you like to answer one of these unanswered questions instead?














          60 Answers
          60






          active

          oldest

          votes








          60 Answers
          60






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          1 2
          next










          1416














          To do this for any object in JavaScript will not be simple or straightforward. You will run into the problem of erroneously picking up attributes from the object's prototype that should be left in the prototype and not copied to the new instance. If, for instance, you are adding a clone method to Object.prototype, as some answers depict, you will need to explicitly skip that attribute. But what if there are other additional methods added to Object.prototype, or other intermediate prototypes, that you don't know about? In that case, you will copy attributes you shouldn't, so you need to detect unforeseen, non-local attributes with the hasOwnProperty method.



          In addition to non-enumerable attributes, you'll encounter a tougher problem when you try to copy objects that have hidden properties. For example, prototype is a hidden property of a function. Also, an object's prototype is referenced with the attribute __proto__, which is also hidden, and will not be copied by a for/in loop iterating over the source object's attributes. I think __proto__ might be specific to Firefox's JavaScript interpreter and it may be something different in other browsers, but you get the picture. Not everything is enumerable. You can copy a hidden attribute if you know its name, but I don't know of any way to discover it automatically.



          Yet another snag in the quest for an elegant solution is the problem of setting up the prototype inheritance correctly. If your source object's prototype is Object, then simply creating a new general object with {} will work, but if the source's prototype is some descendant of Object, then you are going to be missing the additional members from that prototype which you skipped using the hasOwnProperty filter, or which were in the prototype, but weren't enumerable in the first place. One solution might be to call the source object's constructor property to get the initial copy object and then copy over the attributes, but then you still will not get non-enumerable attributes. For example, a Date object stores its data as a hidden member:



          function clone(obj) {
          if (null == obj || "object" != typeof obj) return obj;
          var copy = obj.constructor();
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
          }
          return copy;
          }

          var d1 = new Date();

          /* Executes function after 5 seconds. */
          setTimeout(function(){
          var d2 = clone(d1);
          alert("d1 = " + d1.toString() + "nd2 = " + d2.toString());
          }, 5000);


          The date string for d1 will be 5 seconds behind that of d2. A way to make one Date the same as another is by calling the setTime method, but that is specific to the Date class. I don't think there is a bullet-proof general solution to this problem, though I would be happy to be wrong!



          When I had to implement general deep copying I ended up compromising by assuming that I would only need to copy a plain Object, Array, Date, String, Number, or Boolean. The last 3 types are immutable, so I could perform a shallow copy and not worry about it changing. I further assumed that any elements contained in Object or Array would also be one of the 6 simple types in that list. This can be accomplished with code like the following:



          function clone(obj) {
          var copy;

          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = clone(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          The above function will work adequately for the 6 simple types I mentioned, as long as the data in the objects and arrays form a tree structure. That is, there isn't more than one reference to the same data in the object. For example:



          // This would be cloneable:
          var tree = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "right" : null,
          "data" : 8
          };

          // This would kind-of work, but you would get 2 copies of the
          // inner node instead of 2 references to the same copy
          var directedAcylicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          directedAcyclicGraph["right"] = directedAcyclicGraph["left"];

          // Cloning this would cause a stack overflow due to infinite recursion:
          var cyclicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          cyclicGraph["right"] = cyclicGraph;


          It will not be able to handle any JavaScript object, but it may be sufficient for many purposes as long as you don't assume that it will just work for anything you throw at it.






          share|improve this answer





















          • 5





            almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

            – Trindaz
            Mar 28 '12 at 0:08








          • 5





            For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

            – Trindaz
            Mar 29 '12 at 6:48






          • 5





            Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

            – KooiInc
            May 20 '12 at 7:42






          • 5





            In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

            – cyon
            Nov 29 '14 at 3:29






          • 4





            Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

            – 1owk3y
            Nov 30 '17 at 23:12


















          1416














          To do this for any object in JavaScript will not be simple or straightforward. You will run into the problem of erroneously picking up attributes from the object's prototype that should be left in the prototype and not copied to the new instance. If, for instance, you are adding a clone method to Object.prototype, as some answers depict, you will need to explicitly skip that attribute. But what if there are other additional methods added to Object.prototype, or other intermediate prototypes, that you don't know about? In that case, you will copy attributes you shouldn't, so you need to detect unforeseen, non-local attributes with the hasOwnProperty method.



          In addition to non-enumerable attributes, you'll encounter a tougher problem when you try to copy objects that have hidden properties. For example, prototype is a hidden property of a function. Also, an object's prototype is referenced with the attribute __proto__, which is also hidden, and will not be copied by a for/in loop iterating over the source object's attributes. I think __proto__ might be specific to Firefox's JavaScript interpreter and it may be something different in other browsers, but you get the picture. Not everything is enumerable. You can copy a hidden attribute if you know its name, but I don't know of any way to discover it automatically.



          Yet another snag in the quest for an elegant solution is the problem of setting up the prototype inheritance correctly. If your source object's prototype is Object, then simply creating a new general object with {} will work, but if the source's prototype is some descendant of Object, then you are going to be missing the additional members from that prototype which you skipped using the hasOwnProperty filter, or which were in the prototype, but weren't enumerable in the first place. One solution might be to call the source object's constructor property to get the initial copy object and then copy over the attributes, but then you still will not get non-enumerable attributes. For example, a Date object stores its data as a hidden member:



          function clone(obj) {
          if (null == obj || "object" != typeof obj) return obj;
          var copy = obj.constructor();
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
          }
          return copy;
          }

          var d1 = new Date();

          /* Executes function after 5 seconds. */
          setTimeout(function(){
          var d2 = clone(d1);
          alert("d1 = " + d1.toString() + "nd2 = " + d2.toString());
          }, 5000);


          The date string for d1 will be 5 seconds behind that of d2. A way to make one Date the same as another is by calling the setTime method, but that is specific to the Date class. I don't think there is a bullet-proof general solution to this problem, though I would be happy to be wrong!



          When I had to implement general deep copying I ended up compromising by assuming that I would only need to copy a plain Object, Array, Date, String, Number, or Boolean. The last 3 types are immutable, so I could perform a shallow copy and not worry about it changing. I further assumed that any elements contained in Object or Array would also be one of the 6 simple types in that list. This can be accomplished with code like the following:



          function clone(obj) {
          var copy;

          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = clone(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          The above function will work adequately for the 6 simple types I mentioned, as long as the data in the objects and arrays form a tree structure. That is, there isn't more than one reference to the same data in the object. For example:



          // This would be cloneable:
          var tree = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "right" : null,
          "data" : 8
          };

          // This would kind-of work, but you would get 2 copies of the
          // inner node instead of 2 references to the same copy
          var directedAcylicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          directedAcyclicGraph["right"] = directedAcyclicGraph["left"];

          // Cloning this would cause a stack overflow due to infinite recursion:
          var cyclicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          cyclicGraph["right"] = cyclicGraph;


          It will not be able to handle any JavaScript object, but it may be sufficient for many purposes as long as you don't assume that it will just work for anything you throw at it.






          share|improve this answer





















          • 5





            almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

            – Trindaz
            Mar 28 '12 at 0:08








          • 5





            For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

            – Trindaz
            Mar 29 '12 at 6:48






          • 5





            Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

            – KooiInc
            May 20 '12 at 7:42






          • 5





            In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

            – cyon
            Nov 29 '14 at 3:29






          • 4





            Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

            – 1owk3y
            Nov 30 '17 at 23:12
















          1416












          1416








          1416







          To do this for any object in JavaScript will not be simple or straightforward. You will run into the problem of erroneously picking up attributes from the object's prototype that should be left in the prototype and not copied to the new instance. If, for instance, you are adding a clone method to Object.prototype, as some answers depict, you will need to explicitly skip that attribute. But what if there are other additional methods added to Object.prototype, or other intermediate prototypes, that you don't know about? In that case, you will copy attributes you shouldn't, so you need to detect unforeseen, non-local attributes with the hasOwnProperty method.



          In addition to non-enumerable attributes, you'll encounter a tougher problem when you try to copy objects that have hidden properties. For example, prototype is a hidden property of a function. Also, an object's prototype is referenced with the attribute __proto__, which is also hidden, and will not be copied by a for/in loop iterating over the source object's attributes. I think __proto__ might be specific to Firefox's JavaScript interpreter and it may be something different in other browsers, but you get the picture. Not everything is enumerable. You can copy a hidden attribute if you know its name, but I don't know of any way to discover it automatically.



          Yet another snag in the quest for an elegant solution is the problem of setting up the prototype inheritance correctly. If your source object's prototype is Object, then simply creating a new general object with {} will work, but if the source's prototype is some descendant of Object, then you are going to be missing the additional members from that prototype which you skipped using the hasOwnProperty filter, or which were in the prototype, but weren't enumerable in the first place. One solution might be to call the source object's constructor property to get the initial copy object and then copy over the attributes, but then you still will not get non-enumerable attributes. For example, a Date object stores its data as a hidden member:



          function clone(obj) {
          if (null == obj || "object" != typeof obj) return obj;
          var copy = obj.constructor();
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
          }
          return copy;
          }

          var d1 = new Date();

          /* Executes function after 5 seconds. */
          setTimeout(function(){
          var d2 = clone(d1);
          alert("d1 = " + d1.toString() + "nd2 = " + d2.toString());
          }, 5000);


          The date string for d1 will be 5 seconds behind that of d2. A way to make one Date the same as another is by calling the setTime method, but that is specific to the Date class. I don't think there is a bullet-proof general solution to this problem, though I would be happy to be wrong!



          When I had to implement general deep copying I ended up compromising by assuming that I would only need to copy a plain Object, Array, Date, String, Number, or Boolean. The last 3 types are immutable, so I could perform a shallow copy and not worry about it changing. I further assumed that any elements contained in Object or Array would also be one of the 6 simple types in that list. This can be accomplished with code like the following:



          function clone(obj) {
          var copy;

          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = clone(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          The above function will work adequately for the 6 simple types I mentioned, as long as the data in the objects and arrays form a tree structure. That is, there isn't more than one reference to the same data in the object. For example:



          // This would be cloneable:
          var tree = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "right" : null,
          "data" : 8
          };

          // This would kind-of work, but you would get 2 copies of the
          // inner node instead of 2 references to the same copy
          var directedAcylicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          directedAcyclicGraph["right"] = directedAcyclicGraph["left"];

          // Cloning this would cause a stack overflow due to infinite recursion:
          var cyclicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          cyclicGraph["right"] = cyclicGraph;


          It will not be able to handle any JavaScript object, but it may be sufficient for many purposes as long as you don't assume that it will just work for anything you throw at it.






          share|improve this answer















          To do this for any object in JavaScript will not be simple or straightforward. You will run into the problem of erroneously picking up attributes from the object's prototype that should be left in the prototype and not copied to the new instance. If, for instance, you are adding a clone method to Object.prototype, as some answers depict, you will need to explicitly skip that attribute. But what if there are other additional methods added to Object.prototype, or other intermediate prototypes, that you don't know about? In that case, you will copy attributes you shouldn't, so you need to detect unforeseen, non-local attributes with the hasOwnProperty method.



          In addition to non-enumerable attributes, you'll encounter a tougher problem when you try to copy objects that have hidden properties. For example, prototype is a hidden property of a function. Also, an object's prototype is referenced with the attribute __proto__, which is also hidden, and will not be copied by a for/in loop iterating over the source object's attributes. I think __proto__ might be specific to Firefox's JavaScript interpreter and it may be something different in other browsers, but you get the picture. Not everything is enumerable. You can copy a hidden attribute if you know its name, but I don't know of any way to discover it automatically.



          Yet another snag in the quest for an elegant solution is the problem of setting up the prototype inheritance correctly. If your source object's prototype is Object, then simply creating a new general object with {} will work, but if the source's prototype is some descendant of Object, then you are going to be missing the additional members from that prototype which you skipped using the hasOwnProperty filter, or which were in the prototype, but weren't enumerable in the first place. One solution might be to call the source object's constructor property to get the initial copy object and then copy over the attributes, but then you still will not get non-enumerable attributes. For example, a Date object stores its data as a hidden member:



          function clone(obj) {
          if (null == obj || "object" != typeof obj) return obj;
          var copy = obj.constructor();
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
          }
          return copy;
          }

          var d1 = new Date();

          /* Executes function after 5 seconds. */
          setTimeout(function(){
          var d2 = clone(d1);
          alert("d1 = " + d1.toString() + "nd2 = " + d2.toString());
          }, 5000);


          The date string for d1 will be 5 seconds behind that of d2. A way to make one Date the same as another is by calling the setTime method, but that is specific to the Date class. I don't think there is a bullet-proof general solution to this problem, though I would be happy to be wrong!



          When I had to implement general deep copying I ended up compromising by assuming that I would only need to copy a plain Object, Array, Date, String, Number, or Boolean. The last 3 types are immutable, so I could perform a shallow copy and not worry about it changing. I further assumed that any elements contained in Object or Array would also be one of the 6 simple types in that list. This can be accomplished with code like the following:



          function clone(obj) {
          var copy;

          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = clone(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          The above function will work adequately for the 6 simple types I mentioned, as long as the data in the objects and arrays form a tree structure. That is, there isn't more than one reference to the same data in the object. For example:



          // This would be cloneable:
          var tree = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "right" : null,
          "data" : 8
          };

          // This would kind-of work, but you would get 2 copies of the
          // inner node instead of 2 references to the same copy
          var directedAcylicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          directedAcyclicGraph["right"] = directedAcyclicGraph["left"];

          // Cloning this would cause a stack overflow due to infinite recursion:
          var cyclicGraph = {
          "left" : { "left" : null, "right" : null, "data" : 3 },
          "data" : 8
          };
          cyclicGraph["right"] = cyclicGraph;


          It will not be able to handle any JavaScript object, but it may be sufficient for many purposes as long as you don't assume that it will just work for anything you throw at it.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 14 '18 at 15:12


























          community wiki





          13 revs, 9 users 78%
          A. Levy









          • 5





            almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

            – Trindaz
            Mar 28 '12 at 0:08








          • 5





            For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

            – Trindaz
            Mar 29 '12 at 6:48






          • 5





            Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

            – KooiInc
            May 20 '12 at 7:42






          • 5





            In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

            – cyon
            Nov 29 '14 at 3:29






          • 4





            Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

            – 1owk3y
            Nov 30 '17 at 23:12
















          • 5





            almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

            – Trindaz
            Mar 28 '12 at 0:08








          • 5





            For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

            – Trindaz
            Mar 29 '12 at 6:48






          • 5





            Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

            – KooiInc
            May 20 '12 at 7:42






          • 5





            In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

            – cyon
            Nov 29 '14 at 3:29






          • 4





            Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

            – 1owk3y
            Nov 30 '17 at 23:12










          5




          5





          almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

          – Trindaz
          Mar 28 '12 at 0:08







          almost worked fine in a nodejs - just had to change the line for (var i = 0, var len = obj.length; i < len; ++i) { to for (var i = 0; i < obj.length; ++i) {

          – Trindaz
          Mar 28 '12 at 0:08






          5




          5





          For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

          – Trindaz
          Mar 29 '12 at 6:48





          For future googlers: same deep copy, passing references recursively instead of using 'return' statements at gist.github.com/2234277

          – Trindaz
          Mar 29 '12 at 6:48




          5




          5





          Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

          – KooiInc
          May 20 '12 at 7:42





          Would nowadays JSON.parse(JSON.stringify([some object]),[some revirer function]) be a solution?

          – KooiInc
          May 20 '12 at 7:42




          5




          5





          In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

          – cyon
          Nov 29 '14 at 3:29





          In the first snippet, are you sure it shouldn't be var cpy = new obj.constructor()?

          – cyon
          Nov 29 '14 at 3:29




          4




          4





          Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

          – 1owk3y
          Nov 30 '17 at 23:12







          Object assign doesn't seem to make a true copy in Chrome, maintains reference to original object - ended up using JSON.stringify and JSON.parse to clone - worked perfectly

          – 1owk3y
          Nov 30 '17 at 23:12















          832














          If you do not use functions within your object, a very simple one liner can be the following:



          var cloneOfA = JSON.parse(JSON.stringify(a));


          This works for all kind of objects containing objects, arrays, strings, booleans and numbers.



          See also this article about the structured clone algorithm of browsers which is used when posting messages to and from a worker. It also contains a function for deep cloning.






          share|improve this answer





















          • 39





            Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

            – Nux
            Aug 12 '13 at 18:56








          • 66





            @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

            – BeauCielBleu
            May 14 '14 at 15:27








          • 12





            I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

            – mirhagk
            Oct 7 '14 at 21:08






          • 29





            It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

            – kumar_harsh
            Oct 8 '14 at 8:42






          • 11





            2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

            – James Foster
            Feb 10 '16 at 12:15


















          832














          If you do not use functions within your object, a very simple one liner can be the following:



          var cloneOfA = JSON.parse(JSON.stringify(a));


          This works for all kind of objects containing objects, arrays, strings, booleans and numbers.



          See also this article about the structured clone algorithm of browsers which is used when posting messages to and from a worker. It also contains a function for deep cloning.






          share|improve this answer





















          • 39





            Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

            – Nux
            Aug 12 '13 at 18:56








          • 66





            @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

            – BeauCielBleu
            May 14 '14 at 15:27








          • 12





            I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

            – mirhagk
            Oct 7 '14 at 21:08






          • 29





            It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

            – kumar_harsh
            Oct 8 '14 at 8:42






          • 11





            2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

            – James Foster
            Feb 10 '16 at 12:15
















          832












          832








          832







          If you do not use functions within your object, a very simple one liner can be the following:



          var cloneOfA = JSON.parse(JSON.stringify(a));


          This works for all kind of objects containing objects, arrays, strings, booleans and numbers.



          See also this article about the structured clone algorithm of browsers which is used when posting messages to and from a worker. It also contains a function for deep cloning.






          share|improve this answer















          If you do not use functions within your object, a very simple one liner can be the following:



          var cloneOfA = JSON.parse(JSON.stringify(a));


          This works for all kind of objects containing objects, arrays, strings, booleans and numbers.



          See also this article about the structured clone algorithm of browsers which is used when posting messages to and from a worker. It also contains a function for deep cloning.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 26 '16 at 14:44


























          community wiki





          9 revs, 2 users 96%
          heinob









          • 39





            Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

            – Nux
            Aug 12 '13 at 18:56








          • 66





            @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

            – BeauCielBleu
            May 14 '14 at 15:27








          • 12





            I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

            – mirhagk
            Oct 7 '14 at 21:08






          • 29





            It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

            – kumar_harsh
            Oct 8 '14 at 8:42






          • 11





            2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

            – James Foster
            Feb 10 '16 at 12:15
















          • 39





            Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

            – Nux
            Aug 12 '13 at 18:56








          • 66





            @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

            – BeauCielBleu
            May 14 '14 at 15:27








          • 12





            I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

            – mirhagk
            Oct 7 '14 at 21:08






          • 29





            It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

            – kumar_harsh
            Oct 8 '14 at 8:42






          • 11





            2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

            – James Foster
            Feb 10 '16 at 12:15










          39




          39





          Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

          – Nux
          Aug 12 '13 at 18:56







          Note that this can only be used for testing. Firstly, it's far from optimal in terms of time and memory consumption. Secondly, not all browsers have this methods.

          – Nux
          Aug 12 '13 at 18:56






          66




          66





          @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

          – BeauCielBleu
          May 14 '14 at 15:27







          @Nux, Why not optimal in terms of time and memory? MiJyn says: "The reason why this method is slower than shallow copying (on a deep object) is that this method, by definition, deep copies. But since JSON is implemented in native code (in most browsers), this will be considerably faster than using any other javascript-based deep copying solution, and may sometimes be faster than a javascript-based shallow copying technique (see: jsperf.com/cloning-an-object/79)." stackoverflow.com/questions/122102/…

          – BeauCielBleu
          May 14 '14 at 15:27






          12




          12





          I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

          – mirhagk
          Oct 7 '14 at 21:08





          I just want to add an update to this for Oct. 2014. Chrome 37+ is faster with JSON.parse(JSON.stringify(oldObject)); The benefit of using this is that it's very easy for a javascript engine to see and optimize into something better if it wants.

          – mirhagk
          Oct 7 '14 at 21:08




          29




          29





          It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

          – kumar_harsh
          Oct 8 '14 at 8:42





          It would crap all over the JSON if the object has un-stringify-able things such as Infinity, undefined, etc. Try this object: a = { b: Infinity, c: undefined }

          – kumar_harsh
          Oct 8 '14 at 8:42




          11




          11





          2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

          – James Foster
          Feb 10 '16 at 12:15







          2016 update: This ought to now work in pretty much every browser being widely used. (see Can I use...) The main question now would be whether it is sufficiently performant.

          – James Foster
          Feb 10 '16 at 12:15













          747














          With jQuery, you can shallow copy with extend:



          var copiedObject = jQuery.extend({}, originalObject)


          subsequent changes to the copiedObject will not affect the originalObject, and vice versa.



          Or to make a deep copy:



          var copiedObject = jQuery.extend(true, {}, originalObject)





          share|improve this answer





















          • 163





            or even: var copiedObject = jQuery.extend({},originalObject);

            – Grant McLean
            May 8 '11 at 2:11






          • 81





            Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

            – Will Shaver
            Jun 21 '11 at 0:19








          • 6





            Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

            – Garry English
            Nov 16 '11 at 16:31






          • 3





            @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

            – thorinkor
            Oct 17 '13 at 8:41






          • 3





            Just a note, this doesn't copy the proto constructor of the original object

            – Sam Jones
            May 30 '14 at 15:20
















          747














          With jQuery, you can shallow copy with extend:



          var copiedObject = jQuery.extend({}, originalObject)


          subsequent changes to the copiedObject will not affect the originalObject, and vice versa.



          Or to make a deep copy:



          var copiedObject = jQuery.extend(true, {}, originalObject)





          share|improve this answer





















          • 163





            or even: var copiedObject = jQuery.extend({},originalObject);

            – Grant McLean
            May 8 '11 at 2:11






          • 81





            Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

            – Will Shaver
            Jun 21 '11 at 0:19








          • 6





            Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

            – Garry English
            Nov 16 '11 at 16:31






          • 3





            @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

            – thorinkor
            Oct 17 '13 at 8:41






          • 3





            Just a note, this doesn't copy the proto constructor of the original object

            – Sam Jones
            May 30 '14 at 15:20














          747












          747








          747







          With jQuery, you can shallow copy with extend:



          var copiedObject = jQuery.extend({}, originalObject)


          subsequent changes to the copiedObject will not affect the originalObject, and vice versa.



          Or to make a deep copy:



          var copiedObject = jQuery.extend(true, {}, originalObject)





          share|improve this answer















          With jQuery, you can shallow copy with extend:



          var copiedObject = jQuery.extend({}, originalObject)


          subsequent changes to the copiedObject will not affect the originalObject, and vice versa.



          Or to make a deep copy:



          var copiedObject = jQuery.extend(true, {}, originalObject)






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 18 '16 at 13:28


























          community wiki





          5 revs, 5 users 32%
          Pascal









          • 163





            or even: var copiedObject = jQuery.extend({},originalObject);

            – Grant McLean
            May 8 '11 at 2:11






          • 81





            Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

            – Will Shaver
            Jun 21 '11 at 0:19








          • 6





            Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

            – Garry English
            Nov 16 '11 at 16:31






          • 3





            @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

            – thorinkor
            Oct 17 '13 at 8:41






          • 3





            Just a note, this doesn't copy the proto constructor of the original object

            – Sam Jones
            May 30 '14 at 15:20














          • 163





            or even: var copiedObject = jQuery.extend({},originalObject);

            – Grant McLean
            May 8 '11 at 2:11






          • 81





            Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

            – Will Shaver
            Jun 21 '11 at 0:19








          • 6





            Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

            – Garry English
            Nov 16 '11 at 16:31






          • 3





            @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

            – thorinkor
            Oct 17 '13 at 8:41






          • 3





            Just a note, this doesn't copy the proto constructor of the original object

            – Sam Jones
            May 30 '14 at 15:20








          163




          163





          or even: var copiedObject = jQuery.extend({},originalObject);

          – Grant McLean
          May 8 '11 at 2:11





          or even: var copiedObject = jQuery.extend({},originalObject);

          – Grant McLean
          May 8 '11 at 2:11




          81




          81





          Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

          – Will Shaver
          Jun 21 '11 at 0:19







          Also useful to specify true as the first param for deep copy: jQuery.extend(true, {}, originalObject);

          – Will Shaver
          Jun 21 '11 at 0:19






          6




          6





          Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

          – Garry English
          Nov 16 '11 at 16:31





          Yes, I found this link helpful (same solution as Pascal) stackoverflow.com/questions/122102/…

          – Garry English
          Nov 16 '11 at 16:31




          3




          3





          @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

          – thorinkor
          Oct 17 '13 at 8:41





          @Will Shaver - YES! That's it! Without option of deep copy it didn't work for me!

          – thorinkor
          Oct 17 '13 at 8:41




          3




          3





          Just a note, this doesn't copy the proto constructor of the original object

          – Sam Jones
          May 30 '14 at 15:20





          Just a note, this doesn't copy the proto constructor of the original object

          – Sam Jones
          May 30 '14 at 15:20











          583














          In ECMAScript 6 there is Object.assign method, which copies values of all enumerable own properties from one object to another. For example:



          var x = {myProp: "value"};
          var y = Object.assign({}, x);


          But be aware that nested objects are still copied as reference.






          share|improve this answer


























          • Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

            – user339827
            Feb 11 '16 at 0:52






          • 211





            But be aware that this makes a shallow copy only. Nested objects are still copied as references!

            – ohager
            Mar 28 '16 at 12:30






          • 18





            Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

            – Marcus Junius Brutus
            Mar 29 '16 at 15:09








          • 14





            I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

            – Saulius
            May 29 '16 at 15:09






          • 1





            This is the same as @EugeneTiurin his answer.

            – Wilt
            Jun 9 '16 at 10:07
















          583














          In ECMAScript 6 there is Object.assign method, which copies values of all enumerable own properties from one object to another. For example:



          var x = {myProp: "value"};
          var y = Object.assign({}, x);


          But be aware that nested objects are still copied as reference.






          share|improve this answer


























          • Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

            – user339827
            Feb 11 '16 at 0:52






          • 211





            But be aware that this makes a shallow copy only. Nested objects are still copied as references!

            – ohager
            Mar 28 '16 at 12:30






          • 18





            Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

            – Marcus Junius Brutus
            Mar 29 '16 at 15:09








          • 14





            I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

            – Saulius
            May 29 '16 at 15:09






          • 1





            This is the same as @EugeneTiurin his answer.

            – Wilt
            Jun 9 '16 at 10:07














          583












          583








          583







          In ECMAScript 6 there is Object.assign method, which copies values of all enumerable own properties from one object to another. For example:



          var x = {myProp: "value"};
          var y = Object.assign({}, x);


          But be aware that nested objects are still copied as reference.






          share|improve this answer















          In ECMAScript 6 there is Object.assign method, which copies values of all enumerable own properties from one object to another. For example:



          var x = {myProp: "value"};
          var y = Object.assign({}, x);


          But be aware that nested objects are still copied as reference.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 21 '16 at 11:14


























          community wiki





          3 revs, 3 users 83%
          Vitalii Fedorenko














          • Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

            – user339827
            Feb 11 '16 at 0:52






          • 211





            But be aware that this makes a shallow copy only. Nested objects are still copied as references!

            – ohager
            Mar 28 '16 at 12:30






          • 18





            Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

            – Marcus Junius Brutus
            Mar 29 '16 at 15:09








          • 14





            I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

            – Saulius
            May 29 '16 at 15:09






          • 1





            This is the same as @EugeneTiurin his answer.

            – Wilt
            Jun 9 '16 at 10:07



















          • Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

            – user339827
            Feb 11 '16 at 0:52






          • 211





            But be aware that this makes a shallow copy only. Nested objects are still copied as references!

            – ohager
            Mar 28 '16 at 12:30






          • 18





            Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

            – Marcus Junius Brutus
            Mar 29 '16 at 15:09








          • 14





            I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

            – Saulius
            May 29 '16 at 15:09






          • 1





            This is the same as @EugeneTiurin his answer.

            – Wilt
            Jun 9 '16 at 10:07

















          Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

          – user339827
          Feb 11 '16 at 0:52





          Yeah, I believe that Object.assign is the way to go. It's easy to polyfill it too: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

          – user339827
          Feb 11 '16 at 0:52




          211




          211





          But be aware that this makes a shallow copy only. Nested objects are still copied as references!

          – ohager
          Mar 28 '16 at 12:30





          But be aware that this makes a shallow copy only. Nested objects are still copied as references!

          – ohager
          Mar 28 '16 at 12:30




          18




          18





          Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

          – Marcus Junius Brutus
          Mar 29 '16 at 15:09







          Also be aware that this will copy over "methods" defined via object literals (since these are enumerable) but not methods defied via the "class" mechanism (since these aren't enumerable).

          – Marcus Junius Brutus
          Mar 29 '16 at 15:09






          14




          14





          I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

          – Saulius
          May 29 '16 at 15:09





          I think should be mentioned that this is not suported by IE except Edge. Some people still use this.

          – Saulius
          May 29 '16 at 15:09




          1




          1





          This is the same as @EugeneTiurin his answer.

          – Wilt
          Jun 9 '16 at 10:07





          This is the same as @EugeneTiurin his answer.

          – Wilt
          Jun 9 '16 at 10:07











          164














          Per MDN:




          • If you want shallow copy, use Object.assign({}, a)

          • For "deep" copy, use JSON.parse(JSON.stringify(a))


          There is no need for external libraries but you need to check browser compatibility first.






          share|improve this answer





















          • 6





            JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

            – Edza
            Apr 5 '17 at 9:54






          • 3





            JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

            – Steve Seeger
            Apr 12 '18 at 20:34











          • for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

            – Tareq
            Apr 12 '18 at 21:34











          • works like a charm!

            – Bilal Ahmad
            Aug 16 '18 at 14:26











          • This is good but take care if the object has functions inside

            – Zloy Smiertniy
            Mar 14 at 12:32
















          164














          Per MDN:




          • If you want shallow copy, use Object.assign({}, a)

          • For "deep" copy, use JSON.parse(JSON.stringify(a))


          There is no need for external libraries but you need to check browser compatibility first.






          share|improve this answer





















          • 6





            JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

            – Edza
            Apr 5 '17 at 9:54






          • 3





            JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

            – Steve Seeger
            Apr 12 '18 at 20:34











          • for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

            – Tareq
            Apr 12 '18 at 21:34











          • works like a charm!

            – Bilal Ahmad
            Aug 16 '18 at 14:26











          • This is good but take care if the object has functions inside

            – Zloy Smiertniy
            Mar 14 at 12:32














          164












          164








          164







          Per MDN:




          • If you want shallow copy, use Object.assign({}, a)

          • For "deep" copy, use JSON.parse(JSON.stringify(a))


          There is no need for external libraries but you need to check browser compatibility first.






          share|improve this answer















          Per MDN:




          • If you want shallow copy, use Object.assign({}, a)

          • For "deep" copy, use JSON.parse(JSON.stringify(a))


          There is no need for external libraries but you need to check browser compatibility first.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 8 '18 at 7:42


























          community wiki





          3 revs, 2 users 95%
          Tareq









          • 6





            JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

            – Edza
            Apr 5 '17 at 9:54






          • 3





            JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

            – Steve Seeger
            Apr 12 '18 at 20:34











          • for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

            – Tareq
            Apr 12 '18 at 21:34











          • works like a charm!

            – Bilal Ahmad
            Aug 16 '18 at 14:26











          • This is good but take care if the object has functions inside

            – Zloy Smiertniy
            Mar 14 at 12:32














          • 6





            JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

            – Edza
            Apr 5 '17 at 9:54






          • 3





            JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

            – Steve Seeger
            Apr 12 '18 at 20:34











          • for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

            – Tareq
            Apr 12 '18 at 21:34











          • works like a charm!

            – Bilal Ahmad
            Aug 16 '18 at 14:26











          • This is good but take care if the object has functions inside

            – Zloy Smiertniy
            Mar 14 at 12:32








          6




          6





          JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

          – Edza
          Apr 5 '17 at 9:54





          JSON.parse(JSON.stringify(a)) looks beautiful, but before using it I recommend benchmarking the time it takes for your desired collection. Depending on object size, this might not be the quickest option at all.

          – Edza
          Apr 5 '17 at 9:54




          3




          3





          JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

          – Steve Seeger
          Apr 12 '18 at 20:34





          JSON method I noticed converts date objects to strings but not back to dates. Have to deal with the fun of time-zones in Javascript and manually fix any dates. May be similar cases for other types besides dates

          – Steve Seeger
          Apr 12 '18 at 20:34













          for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

          – Tareq
          Apr 12 '18 at 21:34





          for Date, I would use moment.js since it has clone functionality. see more here momentjs.com/docs/#/parsing/moment-clone

          – Tareq
          Apr 12 '18 at 21:34













          works like a charm!

          – Bilal Ahmad
          Aug 16 '18 at 14:26





          works like a charm!

          – Bilal Ahmad
          Aug 16 '18 at 14:26













          This is good but take care if the object has functions inside

          – Zloy Smiertniy
          Mar 14 at 12:32





          This is good but take care if the object has functions inside

          – Zloy Smiertniy
          Mar 14 at 12:32











          128














          There are many answers, but none that mentions Object.create from ECMAScript 5, which admittedly does not give you an exact copy, but sets the source as the prototype of the new object.



          Thus, this is not an exact answer to the question, but it is a one-line solution and thus elegant. And it works best for 2 cases:




          1. Where such inheritance is useful (duh!)

          2. Where the source object won't be modified, thus making the relation between the 2 objects a non issue.


          Example:



          var foo = { a : 1 };
          var bar = Object.create(foo);
          foo.a; // 1
          bar.a; // 1
          foo.a = 2;
          bar.a; // 2 - prototype changed
          bar.a = 3;
          foo.a; // Still 2, since setting bar.a makes it an "own" property


          Why do I consider this solution to be superior? It's native, thus no looping, no recursion. However, older browsers will need a polyfill.






          share|improve this answer


























          • Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

            – zamnuts
            Apr 29 '13 at 8:07






          • 91





            This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

            – d13
            Jan 16 '14 at 16:18






          • 7





            I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

            – froginvasion
            Aug 8 '14 at 15:26






          • 4





            @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

            – d13
            Dec 2 '14 at 14:08






          • 1





            This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

            – prajnavantha
            Jun 11 '17 at 8:28
















          128














          There are many answers, but none that mentions Object.create from ECMAScript 5, which admittedly does not give you an exact copy, but sets the source as the prototype of the new object.



          Thus, this is not an exact answer to the question, but it is a one-line solution and thus elegant. And it works best for 2 cases:




          1. Where such inheritance is useful (duh!)

          2. Where the source object won't be modified, thus making the relation between the 2 objects a non issue.


          Example:



          var foo = { a : 1 };
          var bar = Object.create(foo);
          foo.a; // 1
          bar.a; // 1
          foo.a = 2;
          bar.a; // 2 - prototype changed
          bar.a = 3;
          foo.a; // Still 2, since setting bar.a makes it an "own" property


          Why do I consider this solution to be superior? It's native, thus no looping, no recursion. However, older browsers will need a polyfill.






          share|improve this answer


























          • Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

            – zamnuts
            Apr 29 '13 at 8:07






          • 91





            This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

            – d13
            Jan 16 '14 at 16:18






          • 7





            I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

            – froginvasion
            Aug 8 '14 at 15:26






          • 4





            @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

            – d13
            Dec 2 '14 at 14:08






          • 1





            This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

            – prajnavantha
            Jun 11 '17 at 8:28














          128












          128








          128







          There are many answers, but none that mentions Object.create from ECMAScript 5, which admittedly does not give you an exact copy, but sets the source as the prototype of the new object.



          Thus, this is not an exact answer to the question, but it is a one-line solution and thus elegant. And it works best for 2 cases:




          1. Where such inheritance is useful (duh!)

          2. Where the source object won't be modified, thus making the relation between the 2 objects a non issue.


          Example:



          var foo = { a : 1 };
          var bar = Object.create(foo);
          foo.a; // 1
          bar.a; // 1
          foo.a = 2;
          bar.a; // 2 - prototype changed
          bar.a = 3;
          foo.a; // Still 2, since setting bar.a makes it an "own" property


          Why do I consider this solution to be superior? It's native, thus no looping, no recursion. However, older browsers will need a polyfill.






          share|improve this answer















          There are many answers, but none that mentions Object.create from ECMAScript 5, which admittedly does not give you an exact copy, but sets the source as the prototype of the new object.



          Thus, this is not an exact answer to the question, but it is a one-line solution and thus elegant. And it works best for 2 cases:




          1. Where such inheritance is useful (duh!)

          2. Where the source object won't be modified, thus making the relation between the 2 objects a non issue.


          Example:



          var foo = { a : 1 };
          var bar = Object.create(foo);
          foo.a; // 1
          bar.a; // 1
          foo.a = 2;
          bar.a; // 2 - prototype changed
          bar.a = 3;
          foo.a; // Still 2, since setting bar.a makes it an "own" property


          Why do I consider this solution to be superior? It's native, thus no looping, no recursion. However, older browsers will need a polyfill.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Mar 19 '12 at 15:17


























          community wiki





          itpastorn














          • Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

            – zamnuts
            Apr 29 '13 at 8:07






          • 91





            This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

            – d13
            Jan 16 '14 at 16:18






          • 7





            I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

            – froginvasion
            Aug 8 '14 at 15:26






          • 4





            @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

            – d13
            Dec 2 '14 at 14:08






          • 1





            This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

            – prajnavantha
            Jun 11 '17 at 8:28



















          • Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

            – zamnuts
            Apr 29 '13 at 8:07






          • 91





            This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

            – d13
            Jan 16 '14 at 16:18






          • 7





            I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

            – froginvasion
            Aug 8 '14 at 15:26






          • 4





            @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

            – d13
            Dec 2 '14 at 14:08






          • 1





            This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

            – prajnavantha
            Jun 11 '17 at 8:28

















          Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

          – zamnuts
          Apr 29 '13 at 8:07





          Note: Object.create is not a deep copy (itpastorn mentioned no recursion). Proof: var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;

          – zamnuts
          Apr 29 '13 at 8:07




          91




          91





          This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

          – d13
          Jan 16 '14 at 16:18





          This is prototypal inheritance, not cloning. These are completely different things. The new object doesn't have any of it's own properties, it just points to the prototype's properties. The point of cloning is to create a fresh new object that doesn't reference any properties in another object.

          – d13
          Jan 16 '14 at 16:18




          7




          7





          I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

          – froginvasion
          Aug 8 '14 at 15:26





          I agree with you completely. I do agree as well that this is not cloning as might be 'intended'. But come on people, embrace the nature of JavaScript instead of trying to find obscure solutions that are not standardized. Sure, you don't like prototypes and they are all "blah" to you, but they are in fact very useful if you know what you're doing.

          – froginvasion
          Aug 8 '14 at 15:26




          4




          4





          @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

          – d13
          Dec 2 '14 at 14:08





          @RobG:This article explains the difference between referencing and cloning: en.wikipedia.org/wiki/Cloning_(programming). Object.create points to the parent's properties through references.That means if the parent's property values change, the child's will also change. This has some surprising side-effects with nested arrays and objects that could lead to hard-to-find bugs in your code if you're not aware of them: jsbin.com/EKivInO/2. A cloned object is a completely new, independent object that has the same properties and values as the parent, but isn't connected to the parent.

          – d13
          Dec 2 '14 at 14:08




          1




          1





          This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

          – prajnavantha
          Jun 11 '17 at 8:28





          This misleads people... Object.create() can be used as a means for inheritance but cloning is nowhere near to it.

          – prajnavantha
          Jun 11 '17 at 8:28











          112














          An elegant way to clone a Javascript object in one line of code



          An Object.assign method is part of the ECMAScript 2015 (ES6) standard and does exactly what you need.



          var clone = Object.assign({}, obj);



          The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.




          Read more...



          The polyfill to support older browsers:



          if (!Object.assign) {
          Object.defineProperty(Object, 'assign', {
          enumerable: false,
          configurable: true,
          writable: true,
          value: function(target) {
          'use strict';
          if (target === undefined || target === null) {
          throw new TypeError('Cannot convert first argument to object');
          }

          var to = Object(target);
          for (var i = 1; i < arguments.length; i++) {
          var nextSource = arguments[i];
          if (nextSource === undefined || nextSource === null) {
          continue;
          }
          nextSource = Object(nextSource);

          var keysArray = Object.keys(nextSource);
          for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
          to[nextKey] = nextSource[nextKey];
          }
          }
          }
          return to;
          }
          });
          }





          share|improve this answer


























          • Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

            – Qwertie
            May 31 '16 at 23:14











          • @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

            – Eugene Tiurin
            Jun 2 '16 at 10:56











          • Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

            – Qwertie
            Jun 3 '16 at 15:20






          • 32





            this will only perform a shallow "cloning"

            – Marcus Junius Brutus
            Jul 25 '16 at 13:27













          • This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

            – Zloy Smiertniy
            Mar 14 at 12:36
















          112














          An elegant way to clone a Javascript object in one line of code



          An Object.assign method is part of the ECMAScript 2015 (ES6) standard and does exactly what you need.



          var clone = Object.assign({}, obj);



          The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.




          Read more...



          The polyfill to support older browsers:



          if (!Object.assign) {
          Object.defineProperty(Object, 'assign', {
          enumerable: false,
          configurable: true,
          writable: true,
          value: function(target) {
          'use strict';
          if (target === undefined || target === null) {
          throw new TypeError('Cannot convert first argument to object');
          }

          var to = Object(target);
          for (var i = 1; i < arguments.length; i++) {
          var nextSource = arguments[i];
          if (nextSource === undefined || nextSource === null) {
          continue;
          }
          nextSource = Object(nextSource);

          var keysArray = Object.keys(nextSource);
          for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
          to[nextKey] = nextSource[nextKey];
          }
          }
          }
          return to;
          }
          });
          }





          share|improve this answer


























          • Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

            – Qwertie
            May 31 '16 at 23:14











          • @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

            – Eugene Tiurin
            Jun 2 '16 at 10:56











          • Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

            – Qwertie
            Jun 3 '16 at 15:20






          • 32





            this will only perform a shallow "cloning"

            – Marcus Junius Brutus
            Jul 25 '16 at 13:27













          • This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

            – Zloy Smiertniy
            Mar 14 at 12:36














          112












          112








          112







          An elegant way to clone a Javascript object in one line of code



          An Object.assign method is part of the ECMAScript 2015 (ES6) standard and does exactly what you need.



          var clone = Object.assign({}, obj);



          The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.




          Read more...



          The polyfill to support older browsers:



          if (!Object.assign) {
          Object.defineProperty(Object, 'assign', {
          enumerable: false,
          configurable: true,
          writable: true,
          value: function(target) {
          'use strict';
          if (target === undefined || target === null) {
          throw new TypeError('Cannot convert first argument to object');
          }

          var to = Object(target);
          for (var i = 1; i < arguments.length; i++) {
          var nextSource = arguments[i];
          if (nextSource === undefined || nextSource === null) {
          continue;
          }
          nextSource = Object(nextSource);

          var keysArray = Object.keys(nextSource);
          for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
          to[nextKey] = nextSource[nextKey];
          }
          }
          }
          return to;
          }
          });
          }





          share|improve this answer















          An elegant way to clone a Javascript object in one line of code



          An Object.assign method is part of the ECMAScript 2015 (ES6) standard and does exactly what you need.



          var clone = Object.assign({}, obj);



          The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.




          Read more...



          The polyfill to support older browsers:



          if (!Object.assign) {
          Object.defineProperty(Object, 'assign', {
          enumerable: false,
          configurable: true,
          writable: true,
          value: function(target) {
          'use strict';
          if (target === undefined || target === null) {
          throw new TypeError('Cannot convert first argument to object');
          }

          var to = Object(target);
          for (var i = 1; i < arguments.length; i++) {
          var nextSource = arguments[i];
          if (nextSource === undefined || nextSource === null) {
          continue;
          }
          nextSource = Object(nextSource);

          var keysArray = Object.keys(nextSource);
          for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
          to[nextKey] = nextSource[nextKey];
          }
          }
          }
          return to;
          }
          });
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Dec 15 '15 at 16:42


























          community wiki





          Eugene Tiurin














          • Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

            – Qwertie
            May 31 '16 at 23:14











          • @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

            – Eugene Tiurin
            Jun 2 '16 at 10:56











          • Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

            – Qwertie
            Jun 3 '16 at 15:20






          • 32





            this will only perform a shallow "cloning"

            – Marcus Junius Brutus
            Jul 25 '16 at 13:27













          • This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

            – Zloy Smiertniy
            Mar 14 at 12:36



















          • Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

            – Qwertie
            May 31 '16 at 23:14











          • @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

            – Eugene Tiurin
            Jun 2 '16 at 10:56











          • Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

            – Qwertie
            Jun 3 '16 at 15:20






          • 32





            this will only perform a shallow "cloning"

            – Marcus Junius Brutus
            Jul 25 '16 at 13:27













          • This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

            – Zloy Smiertniy
            Mar 14 at 12:36

















          Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

          – Qwertie
          May 31 '16 at 23:14





          Sorry for the dumb question, but why does Object.assign take two parameters when the value function in the polyfill takes only one parameter?

          – Qwertie
          May 31 '16 at 23:14













          @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

          – Eugene Tiurin
          Jun 2 '16 at 10:56





          @Qwertie yesterday All the arguments are iterated and merged into one object, prioritizing properties from the last passed arg

          – Eugene Tiurin
          Jun 2 '16 at 10:56













          Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

          – Qwertie
          Jun 3 '16 at 15:20





          Oh I see, thanks (I wasn't familiar with the arguments object before.) I'm having trouble finding Object() via Google... it's a typecast, isn't it?

          – Qwertie
          Jun 3 '16 at 15:20




          32




          32





          this will only perform a shallow "cloning"

          – Marcus Junius Brutus
          Jul 25 '16 at 13:27







          this will only perform a shallow "cloning"

          – Marcus Junius Brutus
          Jul 25 '16 at 13:27















          This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

          – Zloy Smiertniy
          Mar 14 at 12:36





          This answer is the exact same as this: stackoverflow.com/questions/122102/… I know it is by the same person but you should reference instead of just copying the answer.

          – Zloy Smiertniy
          Mar 14 at 12:36











          75














          If you're okay with a shallow copy, the underscore.js library has a clone method.



          y = _.clone(x);


          or you can extend it like



          copiedObject = _.extend({},originalObject);





          share|improve this answer





















          • 36





            And lodash has a cloneDeep

            – dule
            Jun 4 '13 at 0:11






          • 2





            Thanks. Using this technique on a Meteor server.

            – Turbo
            Apr 1 '15 at 4:30











          • Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

            – Arnaud Bouchot
            May 16 '18 at 10:08
















          75














          If you're okay with a shallow copy, the underscore.js library has a clone method.



          y = _.clone(x);


          or you can extend it like



          copiedObject = _.extend({},originalObject);





          share|improve this answer





















          • 36





            And lodash has a cloneDeep

            – dule
            Jun 4 '13 at 0:11






          • 2





            Thanks. Using this technique on a Meteor server.

            – Turbo
            Apr 1 '15 at 4:30











          • Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

            – Arnaud Bouchot
            May 16 '18 at 10:08














          75












          75








          75







          If you're okay with a shallow copy, the underscore.js library has a clone method.



          y = _.clone(x);


          or you can extend it like



          copiedObject = _.extend({},originalObject);





          share|improve this answer















          If you're okay with a shallow copy, the underscore.js library has a clone method.



          y = _.clone(x);


          or you can extend it like



          copiedObject = _.extend({},originalObject);






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 19 '15 at 18:47


























          community wiki





          2 revs, 2 users 50%
          dule









          • 36





            And lodash has a cloneDeep

            – dule
            Jun 4 '13 at 0:11






          • 2





            Thanks. Using this technique on a Meteor server.

            – Turbo
            Apr 1 '15 at 4:30











          • Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

            – Arnaud Bouchot
            May 16 '18 at 10:08














          • 36





            And lodash has a cloneDeep

            – dule
            Jun 4 '13 at 0:11






          • 2





            Thanks. Using this technique on a Meteor server.

            – Turbo
            Apr 1 '15 at 4:30











          • Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

            – Arnaud Bouchot
            May 16 '18 at 10:08








          36




          36





          And lodash has a cloneDeep

          – dule
          Jun 4 '13 at 0:11





          And lodash has a cloneDeep

          – dule
          Jun 4 '13 at 0:11




          2




          2





          Thanks. Using this technique on a Meteor server.

          – Turbo
          Apr 1 '15 at 4:30





          Thanks. Using this technique on a Meteor server.

          – Turbo
          Apr 1 '15 at 4:30













          Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

          – Arnaud Bouchot
          May 16 '18 at 10:08





          Merci man! that did the job for me lodash's amazing I've been using it in a while now. got stuck in a vue project as far as I know vue does not have a built in function to clone an object like angular does have (angular.copy)

          – Arnaud Bouchot
          May 16 '18 at 10:08











          74














          There are several issues with most solutions on the internet. So I decided to make a follow-up, which includes, why the accepted answer shouldn't be accepted.



          starting situation



          I want to deep-copy a Javascript Object with all of its children and their children and so on. But since I'm not kind of a normal developer, my Object has normal properties, circular structures and even nested objects.



          So let's create a circular structure and a nested object first.



          function Circ() {
          this.me = this;
          }

          function Nested(y) {
          this.y = y;
          }


          Let's bring everything together in an Object named a.



          var a = {
          x: 'a',
          circ: new Circ(),
          nested: new Nested('a')
          };


          Next, we want to copy a into a variable named b and mutate it.



          var b = a;

          b.x = 'b';
          b.nested.y = 'b';


          You know what happened here because if not you wouldn't even land on this great question.



          console.log(a, b);

          a --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          Now let's find a solution.



          JSON



          The first attempt I tried was using JSON.



          var b = JSON.parse( JSON.stringify( a ) );

          b.x = 'b';
          b.nested.y = 'b';


          Don't waste too much time on it, you'll get TypeError: Converting circular structure to JSON.



          Recursive copy (the accepted "answer")



          Let's have a look at the accepted answer.



          function cloneSO(obj) {
          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          var copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          var copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = cloneSO(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          var copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          Looks good, heh? It's a recursive copy of the object and handles other types as well, like Date, but that wasn't a requirement.



          var b = cloneSO(a);

          b.x = 'b';
          b.nested.y = 'b';


          Recursion and circular structures doesn't work well together... RangeError: Maximum call stack size exceeded



          native solution



          After arguing with my co-worker, my boss asked us what happened, and he found a simple solution after some googling. It's called Object.create.



          var b = Object.create(a);

          b.x = 'b';
          b.nested.y = 'b';


          This solution was added to Javascript some time ago and even handles circular structure.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          ... and you see, it didn't work with the nested structure inside.



          polyfill for the native solution



          There's a polyfill for Object.create in the older browser just like the IE 8. It's something like recommended by Mozilla, and of course, it's not perfect and results in the same problem as the native solution.



          function F() {};
          function clonePF(o) {
          F.prototype = o;
          return new F();
          }

          var b = clonePF(a);

          b.x = 'b';
          b.nested.y = 'b';


          I've put F outside the scope so we can have a look at what instanceof tells us.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> F {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> true


          Same problem as the native solution, but a little bit worse output.



          the better (but not perfect) solution



          When digging around, I found a similar question (In Javascript, when performing a deep copy, how do I avoid a cycle, due to a property being "this"?) to this one, but with a way better solution.



          function cloneDR(o) {
          const gdcc = "__getDeepCircularCopy__";
          if (o !== Object(o)) {
          return o; // primitive value
          }

          var set = gdcc in o,
          cache = o[gdcc],
          result;
          if (set && typeof cache == "function") {
          return cache();
          }
          // else
          o[gdcc] = function() { return result; }; // overwrite
          if (o instanceof Array) {
          result = ;
          for (var i=0; i<o.length; i++) {
          result[i] = cloneDR(o[i]);
          }
          } else {
          result = {};
          for (var prop in o)
          if (prop != gdcc)
          result[prop] = cloneDR(o[prop]);
          else if (set)
          result[prop] = cloneDR(cache);
          }
          if (set) {
          o[gdcc] = cache; // reset
          } else {
          delete o[gdcc]; // unset again
          }
          return result;
          }

          var b = cloneDR(a);

          b.x = 'b';
          b.nested.y = 'b';


          And let's have a look at the output...



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "a"
          }
          }

          b --> Object {
          x: "b",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> false


          The requirements are matched, but there are still some smaller issues, including changing the instance of nested and circ to Object.




          The structure of trees that share a leaf won't be copied, they will become two independent leaves:




                  [Object]                     [Object]
          / /
          / /
          |/_ _| |/_ _|
          [Object] [Object] ===> [Object] [Object]
          / | |
          / | |
          _| |/_ |/ |/
          [Object] [Object] [Object]


          conclusion



          The last solution using recursion and a cache, may not be the best, but it's a real deep-copy of the object. It handles simple properties, circular structures and nested object, but it will mess up the instance of them while cloning.



          jsfiddle






          share|improve this answer





















          • 7





            so the conlcusion is to avoid that problem :)

            – mikus
            Oct 23 '14 at 11:39






          • 2





            An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

            – Amir Mog
            Aug 16 '16 at 16:53








          • 2





            It is shame that JS not includes native clone function.

            – l00k
            Nov 14 '16 at 14:53






          • 1





            Among all the top answers, I feel this is close to the correct one.

            – KTU
            May 15 '17 at 4:24






          • 2





            The best answer here! Hats off to you good sir!

            – Goran
            Aug 23 '18 at 12:14


















          74














          There are several issues with most solutions on the internet. So I decided to make a follow-up, which includes, why the accepted answer shouldn't be accepted.



          starting situation



          I want to deep-copy a Javascript Object with all of its children and their children and so on. But since I'm not kind of a normal developer, my Object has normal properties, circular structures and even nested objects.



          So let's create a circular structure and a nested object first.



          function Circ() {
          this.me = this;
          }

          function Nested(y) {
          this.y = y;
          }


          Let's bring everything together in an Object named a.



          var a = {
          x: 'a',
          circ: new Circ(),
          nested: new Nested('a')
          };


          Next, we want to copy a into a variable named b and mutate it.



          var b = a;

          b.x = 'b';
          b.nested.y = 'b';


          You know what happened here because if not you wouldn't even land on this great question.



          console.log(a, b);

          a --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          Now let's find a solution.



          JSON



          The first attempt I tried was using JSON.



          var b = JSON.parse( JSON.stringify( a ) );

          b.x = 'b';
          b.nested.y = 'b';


          Don't waste too much time on it, you'll get TypeError: Converting circular structure to JSON.



          Recursive copy (the accepted "answer")



          Let's have a look at the accepted answer.



          function cloneSO(obj) {
          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          var copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          var copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = cloneSO(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          var copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          Looks good, heh? It's a recursive copy of the object and handles other types as well, like Date, but that wasn't a requirement.



          var b = cloneSO(a);

          b.x = 'b';
          b.nested.y = 'b';


          Recursion and circular structures doesn't work well together... RangeError: Maximum call stack size exceeded



          native solution



          After arguing with my co-worker, my boss asked us what happened, and he found a simple solution after some googling. It's called Object.create.



          var b = Object.create(a);

          b.x = 'b';
          b.nested.y = 'b';


          This solution was added to Javascript some time ago and even handles circular structure.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          ... and you see, it didn't work with the nested structure inside.



          polyfill for the native solution



          There's a polyfill for Object.create in the older browser just like the IE 8. It's something like recommended by Mozilla, and of course, it's not perfect and results in the same problem as the native solution.



          function F() {};
          function clonePF(o) {
          F.prototype = o;
          return new F();
          }

          var b = clonePF(a);

          b.x = 'b';
          b.nested.y = 'b';


          I've put F outside the scope so we can have a look at what instanceof tells us.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> F {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> true


          Same problem as the native solution, but a little bit worse output.



          the better (but not perfect) solution



          When digging around, I found a similar question (In Javascript, when performing a deep copy, how do I avoid a cycle, due to a property being "this"?) to this one, but with a way better solution.



          function cloneDR(o) {
          const gdcc = "__getDeepCircularCopy__";
          if (o !== Object(o)) {
          return o; // primitive value
          }

          var set = gdcc in o,
          cache = o[gdcc],
          result;
          if (set && typeof cache == "function") {
          return cache();
          }
          // else
          o[gdcc] = function() { return result; }; // overwrite
          if (o instanceof Array) {
          result = ;
          for (var i=0; i<o.length; i++) {
          result[i] = cloneDR(o[i]);
          }
          } else {
          result = {};
          for (var prop in o)
          if (prop != gdcc)
          result[prop] = cloneDR(o[prop]);
          else if (set)
          result[prop] = cloneDR(cache);
          }
          if (set) {
          o[gdcc] = cache; // reset
          } else {
          delete o[gdcc]; // unset again
          }
          return result;
          }

          var b = cloneDR(a);

          b.x = 'b';
          b.nested.y = 'b';


          And let's have a look at the output...



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "a"
          }
          }

          b --> Object {
          x: "b",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> false


          The requirements are matched, but there are still some smaller issues, including changing the instance of nested and circ to Object.




          The structure of trees that share a leaf won't be copied, they will become two independent leaves:




                  [Object]                     [Object]
          / /
          / /
          |/_ _| |/_ _|
          [Object] [Object] ===> [Object] [Object]
          / | |
          / | |
          _| |/_ |/ |/
          [Object] [Object] [Object]


          conclusion



          The last solution using recursion and a cache, may not be the best, but it's a real deep-copy of the object. It handles simple properties, circular structures and nested object, but it will mess up the instance of them while cloning.



          jsfiddle






          share|improve this answer





















          • 7





            so the conlcusion is to avoid that problem :)

            – mikus
            Oct 23 '14 at 11:39






          • 2





            An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

            – Amir Mog
            Aug 16 '16 at 16:53








          • 2





            It is shame that JS not includes native clone function.

            – l00k
            Nov 14 '16 at 14:53






          • 1





            Among all the top answers, I feel this is close to the correct one.

            – KTU
            May 15 '17 at 4:24






          • 2





            The best answer here! Hats off to you good sir!

            – Goran
            Aug 23 '18 at 12:14
















          74












          74








          74







          There are several issues with most solutions on the internet. So I decided to make a follow-up, which includes, why the accepted answer shouldn't be accepted.



          starting situation



          I want to deep-copy a Javascript Object with all of its children and their children and so on. But since I'm not kind of a normal developer, my Object has normal properties, circular structures and even nested objects.



          So let's create a circular structure and a nested object first.



          function Circ() {
          this.me = this;
          }

          function Nested(y) {
          this.y = y;
          }


          Let's bring everything together in an Object named a.



          var a = {
          x: 'a',
          circ: new Circ(),
          nested: new Nested('a')
          };


          Next, we want to copy a into a variable named b and mutate it.



          var b = a;

          b.x = 'b';
          b.nested.y = 'b';


          You know what happened here because if not you wouldn't even land on this great question.



          console.log(a, b);

          a --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          Now let's find a solution.



          JSON



          The first attempt I tried was using JSON.



          var b = JSON.parse( JSON.stringify( a ) );

          b.x = 'b';
          b.nested.y = 'b';


          Don't waste too much time on it, you'll get TypeError: Converting circular structure to JSON.



          Recursive copy (the accepted "answer")



          Let's have a look at the accepted answer.



          function cloneSO(obj) {
          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          var copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          var copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = cloneSO(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          var copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          Looks good, heh? It's a recursive copy of the object and handles other types as well, like Date, but that wasn't a requirement.



          var b = cloneSO(a);

          b.x = 'b';
          b.nested.y = 'b';


          Recursion and circular structures doesn't work well together... RangeError: Maximum call stack size exceeded



          native solution



          After arguing with my co-worker, my boss asked us what happened, and he found a simple solution after some googling. It's called Object.create.



          var b = Object.create(a);

          b.x = 'b';
          b.nested.y = 'b';


          This solution was added to Javascript some time ago and even handles circular structure.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          ... and you see, it didn't work with the nested structure inside.



          polyfill for the native solution



          There's a polyfill for Object.create in the older browser just like the IE 8. It's something like recommended by Mozilla, and of course, it's not perfect and results in the same problem as the native solution.



          function F() {};
          function clonePF(o) {
          F.prototype = o;
          return new F();
          }

          var b = clonePF(a);

          b.x = 'b';
          b.nested.y = 'b';


          I've put F outside the scope so we can have a look at what instanceof tells us.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> F {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> true


          Same problem as the native solution, but a little bit worse output.



          the better (but not perfect) solution



          When digging around, I found a similar question (In Javascript, when performing a deep copy, how do I avoid a cycle, due to a property being "this"?) to this one, but with a way better solution.



          function cloneDR(o) {
          const gdcc = "__getDeepCircularCopy__";
          if (o !== Object(o)) {
          return o; // primitive value
          }

          var set = gdcc in o,
          cache = o[gdcc],
          result;
          if (set && typeof cache == "function") {
          return cache();
          }
          // else
          o[gdcc] = function() { return result; }; // overwrite
          if (o instanceof Array) {
          result = ;
          for (var i=0; i<o.length; i++) {
          result[i] = cloneDR(o[i]);
          }
          } else {
          result = {};
          for (var prop in o)
          if (prop != gdcc)
          result[prop] = cloneDR(o[prop]);
          else if (set)
          result[prop] = cloneDR(cache);
          }
          if (set) {
          o[gdcc] = cache; // reset
          } else {
          delete o[gdcc]; // unset again
          }
          return result;
          }

          var b = cloneDR(a);

          b.x = 'b';
          b.nested.y = 'b';


          And let's have a look at the output...



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "a"
          }
          }

          b --> Object {
          x: "b",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> false


          The requirements are matched, but there are still some smaller issues, including changing the instance of nested and circ to Object.




          The structure of trees that share a leaf won't be copied, they will become two independent leaves:




                  [Object]                     [Object]
          / /
          / /
          |/_ _| |/_ _|
          [Object] [Object] ===> [Object] [Object]
          / | |
          / | |
          _| |/_ |/ |/
          [Object] [Object] [Object]


          conclusion



          The last solution using recursion and a cache, may not be the best, but it's a real deep-copy of the object. It handles simple properties, circular structures and nested object, but it will mess up the instance of them while cloning.



          jsfiddle






          share|improve this answer















          There are several issues with most solutions on the internet. So I decided to make a follow-up, which includes, why the accepted answer shouldn't be accepted.



          starting situation



          I want to deep-copy a Javascript Object with all of its children and their children and so on. But since I'm not kind of a normal developer, my Object has normal properties, circular structures and even nested objects.



          So let's create a circular structure and a nested object first.



          function Circ() {
          this.me = this;
          }

          function Nested(y) {
          this.y = y;
          }


          Let's bring everything together in an Object named a.



          var a = {
          x: 'a',
          circ: new Circ(),
          nested: new Nested('a')
          };


          Next, we want to copy a into a variable named b and mutate it.



          var b = a;

          b.x = 'b';
          b.nested.y = 'b';


          You know what happened here because if not you wouldn't even land on this great question.



          console.log(a, b);

          a --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          Now let's find a solution.



          JSON



          The first attempt I tried was using JSON.



          var b = JSON.parse( JSON.stringify( a ) );

          b.x = 'b';
          b.nested.y = 'b';


          Don't waste too much time on it, you'll get TypeError: Converting circular structure to JSON.



          Recursive copy (the accepted "answer")



          Let's have a look at the accepted answer.



          function cloneSO(obj) {
          // Handle the 3 simple types, and null or undefined
          if (null == obj || "object" != typeof obj) return obj;

          // Handle Date
          if (obj instanceof Date) {
          var copy = new Date();
          copy.setTime(obj.getTime());
          return copy;
          }

          // Handle Array
          if (obj instanceof Array) {
          var copy = ;
          for (var i = 0, len = obj.length; i < len; i++) {
          copy[i] = cloneSO(obj[i]);
          }
          return copy;
          }

          // Handle Object
          if (obj instanceof Object) {
          var copy = {};
          for (var attr in obj) {
          if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
          }
          return copy;
          }

          throw new Error("Unable to copy obj! Its type isn't supported.");
          }


          Looks good, heh? It's a recursive copy of the object and handles other types as well, like Date, but that wasn't a requirement.



          var b = cloneSO(a);

          b.x = 'b';
          b.nested.y = 'b';


          Recursion and circular structures doesn't work well together... RangeError: Maximum call stack size exceeded



          native solution



          After arguing with my co-worker, my boss asked us what happened, and he found a simple solution after some googling. It's called Object.create.



          var b = Object.create(a);

          b.x = 'b';
          b.nested.y = 'b';


          This solution was added to Javascript some time ago and even handles circular structure.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> Object {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }


          ... and you see, it didn't work with the nested structure inside.



          polyfill for the native solution



          There's a polyfill for Object.create in the older browser just like the IE 8. It's something like recommended by Mozilla, and of course, it's not perfect and results in the same problem as the native solution.



          function F() {};
          function clonePF(o) {
          F.prototype = o;
          return new F();
          }

          var b = clonePF(a);

          b.x = 'b';
          b.nested.y = 'b';


          I've put F outside the scope so we can have a look at what instanceof tells us.



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          b --> F {
          x: "b",
          circ: Circ {
          me: Circ { ... }
          },
          nested: Nested {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> true


          Same problem as the native solution, but a little bit worse output.



          the better (but not perfect) solution



          When digging around, I found a similar question (In Javascript, when performing a deep copy, how do I avoid a cycle, due to a property being "this"?) to this one, but with a way better solution.



          function cloneDR(o) {
          const gdcc = "__getDeepCircularCopy__";
          if (o !== Object(o)) {
          return o; // primitive value
          }

          var set = gdcc in o,
          cache = o[gdcc],
          result;
          if (set && typeof cache == "function") {
          return cache();
          }
          // else
          o[gdcc] = function() { return result; }; // overwrite
          if (o instanceof Array) {
          result = ;
          for (var i=0; i<o.length; i++) {
          result[i] = cloneDR(o[i]);
          }
          } else {
          result = {};
          for (var prop in o)
          if (prop != gdcc)
          result[prop] = cloneDR(o[prop]);
          else if (set)
          result[prop] = cloneDR(cache);
          }
          if (set) {
          o[gdcc] = cache; // reset
          } else {
          delete o[gdcc]; // unset again
          }
          return result;
          }

          var b = cloneDR(a);

          b.x = 'b';
          b.nested.y = 'b';


          And let's have a look at the output...



          console.log(a, b);

          a --> Object {
          x: "a",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "a"
          }
          }

          b --> Object {
          x: "b",
          circ: Object {
          me: Object { ... }
          },
          nested: Object {
          y: "b"
          }
          }

          console.log(typeof a, typeof b);

          a --> object
          b --> object

          console.log(a instanceof Object, b instanceof Object);

          a --> true
          b --> true

          console.log(a instanceof F, b instanceof F);

          a --> false
          b --> false


          The requirements are matched, but there are still some smaller issues, including changing the instance of nested and circ to Object.




          The structure of trees that share a leaf won't be copied, they will become two independent leaves:




                  [Object]                     [Object]
          / /
          / /
          |/_ _| |/_ _|
          [Object] [Object] ===> [Object] [Object]
          / | |
          / | |
          _| |/_ |/ |/
          [Object] [Object] [Object]


          conclusion



          The last solution using recursion and a cache, may not be the best, but it's a real deep-copy of the object. It handles simple properties, circular structures and nested object, but it will mess up the instance of them while cloning.



          jsfiddle







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 1 '18 at 8:36


























          community wiki





          6 revs, 4 users 99%
          Fabio Poloni









          • 7





            so the conlcusion is to avoid that problem :)

            – mikus
            Oct 23 '14 at 11:39






          • 2





            An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

            – Amir Mog
            Aug 16 '16 at 16:53








          • 2





            It is shame that JS not includes native clone function.

            – l00k
            Nov 14 '16 at 14:53






          • 1





            Among all the top answers, I feel this is close to the correct one.

            – KTU
            May 15 '17 at 4:24






          • 2





            The best answer here! Hats off to you good sir!

            – Goran
            Aug 23 '18 at 12:14
















          • 7





            so the conlcusion is to avoid that problem :)

            – mikus
            Oct 23 '14 at 11:39






          • 2





            An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

            – Amir Mog
            Aug 16 '16 at 16:53








          • 2





            It is shame that JS not includes native clone function.

            – l00k
            Nov 14 '16 at 14:53






          • 1





            Among all the top answers, I feel this is close to the correct one.

            – KTU
            May 15 '17 at 4:24






          • 2





            The best answer here! Hats off to you good sir!

            – Goran
            Aug 23 '18 at 12:14










          7




          7





          so the conlcusion is to avoid that problem :)

          – mikus
          Oct 23 '14 at 11:39





          so the conlcusion is to avoid that problem :)

          – mikus
          Oct 23 '14 at 11:39




          2




          2





          An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

          – Amir Mog
          Aug 16 '16 at 16:53







          An okay analysis of the solutions provided above but the conclusion drawn by the author indicates that there is no solution to this question.

          – Amir Mog
          Aug 16 '16 at 16:53






          2




          2





          It is shame that JS not includes native clone function.

          – l00k
          Nov 14 '16 at 14:53





          It is shame that JS not includes native clone function.

          – l00k
          Nov 14 '16 at 14:53




          1




          1





          Among all the top answers, I feel this is close to the correct one.

          – KTU
          May 15 '17 at 4:24





          Among all the top answers, I feel this is close to the correct one.

          – KTU
          May 15 '17 at 4:24




          2




          2





          The best answer here! Hats off to you good sir!

          – Goran
          Aug 23 '18 at 12:14







          The best answer here! Hats off to you good sir!

          – Goran
          Aug 23 '18 at 12:14













          38














          One particularly inelegant solution is to use JSON encoding to make deep copies of objects that do not have member methods. The methodology is to JSON encode your target object, then by decoding it, you get the copy you are looking for. You can decode as many times as you want to make as many copies as you need.



          Of course, functions do not belong in JSON, so this only works for objects without member methods.



          This methodology was perfect for my use case, since I'm storing JSON blobs in a key-value store, and when they are exposed as objects in a JavaScript API, each object actually contains a copy of the original state of the object so we can calculate the delta after the caller has mutated the exposed object.



          var object1 = {key:"value"};
          var object2 = object1;

          object2 = JSON.stringify(object1);
          object2 = JSON.parse(object2);

          object2.key = "a change";
          console.log(object1);// returns value





          share|improve this answer


























          • Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

            – the_drow
            Oct 29 '09 at 20:37






          • 4





            Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

            – Kris Walker
            Oct 30 '09 at 10:27






          • 1





            IMHO the best answer, because the OP states "literal-constructed" objects

            – mark
            Oct 4 '11 at 11:35






          • 30





            There's nothing more inelegant than the use of the word unelegant.

            – Kevin Laity
            Jan 26 '12 at 20:18






          • 1





            @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

            – abarnert
            Aug 14 '12 at 1:58
















          38














          One particularly inelegant solution is to use JSON encoding to make deep copies of objects that do not have member methods. The methodology is to JSON encode your target object, then by decoding it, you get the copy you are looking for. You can decode as many times as you want to make as many copies as you need.



          Of course, functions do not belong in JSON, so this only works for objects without member methods.



          This methodology was perfect for my use case, since I'm storing JSON blobs in a key-value store, and when they are exposed as objects in a JavaScript API, each object actually contains a copy of the original state of the object so we can calculate the delta after the caller has mutated the exposed object.



          var object1 = {key:"value"};
          var object2 = object1;

          object2 = JSON.stringify(object1);
          object2 = JSON.parse(object2);

          object2.key = "a change";
          console.log(object1);// returns value





          share|improve this answer


























          • Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

            – the_drow
            Oct 29 '09 at 20:37






          • 4





            Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

            – Kris Walker
            Oct 30 '09 at 10:27






          • 1





            IMHO the best answer, because the OP states "literal-constructed" objects

            – mark
            Oct 4 '11 at 11:35






          • 30





            There's nothing more inelegant than the use of the word unelegant.

            – Kevin Laity
            Jan 26 '12 at 20:18






          • 1





            @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

            – abarnert
            Aug 14 '12 at 1:58














          38












          38








          38







          One particularly inelegant solution is to use JSON encoding to make deep copies of objects that do not have member methods. The methodology is to JSON encode your target object, then by decoding it, you get the copy you are looking for. You can decode as many times as you want to make as many copies as you need.



          Of course, functions do not belong in JSON, so this only works for objects without member methods.



          This methodology was perfect for my use case, since I'm storing JSON blobs in a key-value store, and when they are exposed as objects in a JavaScript API, each object actually contains a copy of the original state of the object so we can calculate the delta after the caller has mutated the exposed object.



          var object1 = {key:"value"};
          var object2 = object1;

          object2 = JSON.stringify(object1);
          object2 = JSON.parse(object2);

          object2.key = "a change";
          console.log(object1);// returns value





          share|improve this answer















          One particularly inelegant solution is to use JSON encoding to make deep copies of objects that do not have member methods. The methodology is to JSON encode your target object, then by decoding it, you get the copy you are looking for. You can decode as many times as you want to make as many copies as you need.



          Of course, functions do not belong in JSON, so this only works for objects without member methods.



          This methodology was perfect for my use case, since I'm storing JSON blobs in a key-value store, and when they are exposed as objects in a JavaScript API, each object actually contains a copy of the original state of the object so we can calculate the delta after the caller has mutated the exposed object.



          var object1 = {key:"value"};
          var object2 = object1;

          object2 = JSON.stringify(object1);
          object2 = JSON.parse(object2);

          object2.key = "a change";
          console.log(object1);// returns value






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 28 '16 at 17:24


























          community wiki





          2 revs, 2 users 60%
          Tim














          • Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

            – the_drow
            Oct 29 '09 at 20:37






          • 4





            Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

            – Kris Walker
            Oct 30 '09 at 10:27






          • 1





            IMHO the best answer, because the OP states "literal-constructed" objects

            – mark
            Oct 4 '11 at 11:35






          • 30





            There's nothing more inelegant than the use of the word unelegant.

            – Kevin Laity
            Jan 26 '12 at 20:18






          • 1





            @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

            – abarnert
            Aug 14 '12 at 1:58



















          • Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

            – the_drow
            Oct 29 '09 at 20:37






          • 4





            Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

            – Kris Walker
            Oct 30 '09 at 10:27






          • 1





            IMHO the best answer, because the OP states "literal-constructed" objects

            – mark
            Oct 4 '11 at 11:35






          • 30





            There's nothing more inelegant than the use of the word unelegant.

            – Kevin Laity
            Jan 26 '12 at 20:18






          • 1





            @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

            – abarnert
            Aug 14 '12 at 1:58

















          Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

          – the_drow
          Oct 29 '09 at 20:37





          Why don't functions belong to JSON? I've seen them transfered as JSON more then once...

          – the_drow
          Oct 29 '09 at 20:37




          4




          4





          Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

          – Kris Walker
          Oct 30 '09 at 10:27





          Functions are not part of the JSON spec becuase they are not a secure (or smart) way to transfer data, which is what JSON was made for. I know the native JSON encoder in Firefox simply ignores functions passed to it, but I'm not sure about the behavior of others.

          – Kris Walker
          Oct 30 '09 at 10:27




          1




          1





          IMHO the best answer, because the OP states "literal-constructed" objects

          – mark
          Oct 4 '11 at 11:35





          IMHO the best answer, because the OP states "literal-constructed" objects

          – mark
          Oct 4 '11 at 11:35




          30




          30





          There's nothing more inelegant than the use of the word unelegant.

          – Kevin Laity
          Jan 26 '12 at 20:18





          There's nothing more inelegant than the use of the word unelegant.

          – Kevin Laity
          Jan 26 '12 at 20:18




          1




          1





          @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

          – abarnert
          Aug 14 '12 at 1:58





          @mark: { 'foo': function() { return 1; } } is a literal-constructed object.

          – abarnert
          Aug 14 '12 at 1:58











          31














          You can simply use a spread property to copy an object without references. But be careful (see comments), the 'copy' is just on the lowest object/array level. Nested properties are still references!





          Complete clone:



          let x = {a: 'value1'}
          let x2 = {...x}

          // => mutate without references:

          x2.a = 'value2'
          console.log(x.a) // => 'value1'


          Clone with references on second level:



          const y = {a: {b: 'value3'}}
          const y2 = {...y}

          // => nested object is still a references:

          y2.a.b = 'value4'
          console.log(y.a.b) // => 'value4'




          JavaScript actually does not support deep clones natively. Use an utility function. For example Ramda:




          http://ramdajs.com/docs/#clone







          share|improve this answer





















          • 1





            This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

            – Kamil Kiełczewski
            Apr 14 '16 at 8:23








          • 3





            This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

            – Bugs Bunny
            May 17 '16 at 13:01











          • A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

            – Cristian Traìna
            Aug 13 '18 at 17:37
















          31














          You can simply use a spread property to copy an object without references. But be careful (see comments), the 'copy' is just on the lowest object/array level. Nested properties are still references!





          Complete clone:



          let x = {a: 'value1'}
          let x2 = {...x}

          // => mutate without references:

          x2.a = 'value2'
          console.log(x.a) // => 'value1'


          Clone with references on second level:



          const y = {a: {b: 'value3'}}
          const y2 = {...y}

          // => nested object is still a references:

          y2.a.b = 'value4'
          console.log(y.a.b) // => 'value4'




          JavaScript actually does not support deep clones natively. Use an utility function. For example Ramda:




          http://ramdajs.com/docs/#clone







          share|improve this answer





















          • 1





            This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

            – Kamil Kiełczewski
            Apr 14 '16 at 8:23








          • 3





            This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

            – Bugs Bunny
            May 17 '16 at 13:01











          • A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

            – Cristian Traìna
            Aug 13 '18 at 17:37














          31












          31








          31







          You can simply use a spread property to copy an object without references. But be careful (see comments), the 'copy' is just on the lowest object/array level. Nested properties are still references!





          Complete clone:



          let x = {a: 'value1'}
          let x2 = {...x}

          // => mutate without references:

          x2.a = 'value2'
          console.log(x.a) // => 'value1'


          Clone with references on second level:



          const y = {a: {b: 'value3'}}
          const y2 = {...y}

          // => nested object is still a references:

          y2.a.b = 'value4'
          console.log(y.a.b) // => 'value4'




          JavaScript actually does not support deep clones natively. Use an utility function. For example Ramda:




          http://ramdajs.com/docs/#clone







          share|improve this answer















          You can simply use a spread property to copy an object without references. But be careful (see comments), the 'copy' is just on the lowest object/array level. Nested properties are still references!





          Complete clone:



          let x = {a: 'value1'}
          let x2 = {...x}

          // => mutate without references:

          x2.a = 'value2'
          console.log(x.a) // => 'value1'


          Clone with references on second level:



          const y = {a: {b: 'value3'}}
          const y2 = {...y}

          // => nested object is still a references:

          y2.a.b = 'value4'
          console.log(y.a.b) // => 'value4'




          JavaScript actually does not support deep clones natively. Use an utility function. For example Ramda:




          http://ramdajs.com/docs/#clone








          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 5 '17 at 12:30


























          community wiki





          5 revs, 3 users 92%
          musemind









          • 1





            This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

            – Kamil Kiełczewski
            Apr 14 '16 at 8:23








          • 3





            This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

            – Bugs Bunny
            May 17 '16 at 13:01











          • A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

            – Cristian Traìna
            Aug 13 '18 at 17:37














          • 1





            This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

            – Kamil Kiełczewski
            Apr 14 '16 at 8:23








          • 3





            This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

            – Bugs Bunny
            May 17 '16 at 13:01











          • A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

            – Cristian Traìna
            Aug 13 '18 at 17:37








          1




          1





          This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

          – Kamil Kiełczewski
          Apr 14 '16 at 8:23







          This not working... it would work probably when x will be an array for instance x= [ 'ab','cd',...]

          – Kamil Kiełczewski
          Apr 14 '16 at 8:23






          3




          3





          This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

          – Bugs Bunny
          May 17 '16 at 13:01





          This works, but bear in mind this is a SHALLOW copy, therefore any deep references to others objects remain references!

          – Bugs Bunny
          May 17 '16 at 13:01













          A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

          – Cristian Traìna
          Aug 13 '18 at 17:37





          A partial clone can also happen in this way: const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}

          – Cristian Traìna
          Aug 13 '18 at 17:37











          31














          OK, imagine you have this object below and you want to clone it:



          let obj = {a:1, b:2, c:3}; //ES6


          or



          var obj = {a:1, b:2, c:3}; //ES5


          the answer is mainly depeneds on which ECMAscript you using, in ES6+, you can simply use Object.assign to do the clone:



          let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};


          or using spread operator like this:



          let cloned = {...obj}; //new {a:1, b:2, c:3};


          But if you using ES5, you can use few methods, but the JSON.stringify, just make sure you not using for a big chunk of data to copy, but it could be one line handy way in many cases, something like this:



          let cloned = JSON.parse(JSON.stringify(obj)); 
          //new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over





          share|improve this answer


























          • Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

            – user1063287
            Sep 14 '18 at 11:04











          • I just use the spread operator (ES6)

            – Shiraz
            Mar 13 at 15:17











          • Right @Shiraz, but that only does a shallow copy...

            – Alireza
            Mar 14 at 9:56











          • Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

            – Alireza
            Mar 14 at 9:58
















          31














          OK, imagine you have this object below and you want to clone it:



          let obj = {a:1, b:2, c:3}; //ES6


          or



          var obj = {a:1, b:2, c:3}; //ES5


          the answer is mainly depeneds on which ECMAscript you using, in ES6+, you can simply use Object.assign to do the clone:



          let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};


          or using spread operator like this:



          let cloned = {...obj}; //new {a:1, b:2, c:3};


          But if you using ES5, you can use few methods, but the JSON.stringify, just make sure you not using for a big chunk of data to copy, but it could be one line handy way in many cases, something like this:



          let cloned = JSON.parse(JSON.stringify(obj)); 
          //new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over





          share|improve this answer


























          • Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

            – user1063287
            Sep 14 '18 at 11:04











          • I just use the spread operator (ES6)

            – Shiraz
            Mar 13 at 15:17











          • Right @Shiraz, but that only does a shallow copy...

            – Alireza
            Mar 14 at 9:56











          • Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

            – Alireza
            Mar 14 at 9:58














          31












          31








          31







          OK, imagine you have this object below and you want to clone it:



          let obj = {a:1, b:2, c:3}; //ES6


          or



          var obj = {a:1, b:2, c:3}; //ES5


          the answer is mainly depeneds on which ECMAscript you using, in ES6+, you can simply use Object.assign to do the clone:



          let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};


          or using spread operator like this:



          let cloned = {...obj}; //new {a:1, b:2, c:3};


          But if you using ES5, you can use few methods, but the JSON.stringify, just make sure you not using for a big chunk of data to copy, but it could be one line handy way in many cases, something like this:



          let cloned = JSON.parse(JSON.stringify(obj)); 
          //new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over





          share|improve this answer















          OK, imagine you have this object below and you want to clone it:



          let obj = {a:1, b:2, c:3}; //ES6


          or



          var obj = {a:1, b:2, c:3}; //ES5


          the answer is mainly depeneds on which ECMAscript you using, in ES6+, you can simply use Object.assign to do the clone:



          let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};


          or using spread operator like this:



          let cloned = {...obj}; //new {a:1, b:2, c:3};


          But if you using ES5, you can use few methods, but the JSON.stringify, just make sure you not using for a big chunk of data to copy, but it could be one line handy way in many cases, something like this:



          let cloned = JSON.parse(JSON.stringify(obj)); 
          //new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 14 at 9:59


























          community wiki





          3 revs
          Alireza














          • Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

            – user1063287
            Sep 14 '18 at 11:04











          • I just use the spread operator (ES6)

            – Shiraz
            Mar 13 at 15:17











          • Right @Shiraz, but that only does a shallow copy...

            – Alireza
            Mar 14 at 9:56











          • Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

            – Alireza
            Mar 14 at 9:58



















          • Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

            – user1063287
            Sep 14 '18 at 11:04











          • I just use the spread operator (ES6)

            – Shiraz
            Mar 13 at 15:17











          • Right @Shiraz, but that only does a shallow copy...

            – Alireza
            Mar 14 at 9:56











          • Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

            – Alireza
            Mar 14 at 9:58

















          Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

          – user1063287
          Sep 14 '18 at 11:04





          Can you please give example of what big chunk of data would equate to? 100kb? 100MB? Thanks!

          – user1063287
          Sep 14 '18 at 11:04













          I just use the spread operator (ES6)

          – Shiraz
          Mar 13 at 15:17





          I just use the spread operator (ES6)

          – Shiraz
          Mar 13 at 15:17













          Right @Shiraz, but that only does a shallow copy...

          – Alireza
          Mar 14 at 9:56





          Right @Shiraz, but that only does a shallow copy...

          – Alireza
          Mar 14 at 9:56













          Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

          – Alireza
          Mar 14 at 9:58





          Yes, @user1063287, that basically the bigger data, the performnce worse... so it really depends, not a kb, mb or gb, it's more about how many times you wanna do that also... Also it won't work for functions and other stuffs...

          – Alireza
          Mar 14 at 9:58











          23














          For those using AngularJS, there is also direct method for cloning or extending of the objects in this library.



          var destination = angular.copy(source);


          or



          angular.copy(source, destination);


          More in angular.copy documentation...






          share|improve this answer





















          • 1





            This is a deep copy FYI.

            – zamnuts
            Sep 19 '14 at 10:27
















          23














          For those using AngularJS, there is also direct method for cloning or extending of the objects in this library.



          var destination = angular.copy(source);


          or



          angular.copy(source, destination);


          More in angular.copy documentation...






          share|improve this answer





















          • 1





            This is a deep copy FYI.

            – zamnuts
            Sep 19 '14 at 10:27














          23












          23








          23







          For those using AngularJS, there is also direct method for cloning or extending of the objects in this library.



          var destination = angular.copy(source);


          or



          angular.copy(source, destination);


          More in angular.copy documentation...






          share|improve this answer















          For those using AngularJS, there is also direct method for cloning or extending of the objects in this library.



          var destination = angular.copy(source);


          or



          angular.copy(source, destination);


          More in angular.copy documentation...







          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Sep 3 '14 at 19:08


























          community wiki





          Lukas Jelinek









          • 1





            This is a deep copy FYI.

            – zamnuts
            Sep 19 '14 at 10:27














          • 1





            This is a deep copy FYI.

            – zamnuts
            Sep 19 '14 at 10:27








          1




          1





          This is a deep copy FYI.

          – zamnuts
          Sep 19 '14 at 10:27





          This is a deep copy FYI.

          – zamnuts
          Sep 19 '14 at 10:27











          21














          A.Levy's answer is almost complete, here is my little contribution: there is a way how to handle recursive references, see this line



          if(this[attr]==this) copy[attr] = copy;



          If the object is XML DOM element, we must use cloneNode instead



          if(this.cloneNode) return this.cloneNode(true);



          Inspired by A.Levy's exhaustive study and Calvin's prototyping approach, I offer this solution:



          Object.prototype.clone = function() {
          if(this.cloneNode) return this.cloneNode(true);
          var copy = this instanceof Array ? : {};
          for(var attr in this) {
          if(typeof this[attr] == "function" || this[attr]==null || !this[attr].clone)
          copy[attr] = this[attr];
          else if(this[attr]==this) copy[attr] = copy;
          else copy[attr] = this[attr].clone();
          }
          return copy;
          }

          Date.prototype.clone = function() {
          var copy = new Date();
          copy.setTime(this.getTime());
          return copy;
          }

          Number.prototype.clone =
          Boolean.prototype.clone =
          String.prototype.clone = function() {
          return this;
          }


          See also Andy Burke's note in the answers.






          share|improve this answer


























          • Does not work well with inheritance.

            – calbertts
            Jan 2 '14 at 18:52






          • 3





            Date.prototype.clone = function() {return new Date(+this)};

            – RobG
            Dec 2 '14 at 12:20
















          21














          A.Levy's answer is almost complete, here is my little contribution: there is a way how to handle recursive references, see this line



          if(this[attr]==this) copy[attr] = copy;



          If the object is XML DOM element, we must use cloneNode instead



          if(this.cloneNode) return this.cloneNode(true);



          Inspired by A.Levy's exhaustive study and Calvin's prototyping approach, I offer this solution:



          Object.prototype.clone = function() {
          if(this.cloneNode) return this.cloneNode(true);
          var copy = this instanceof Array ? : {};
          for(var attr in this) {
          if(typeof this[attr] == "function" || this[attr]==null || !this[attr].clone)
          copy[attr] = this[attr];
          else if(this[attr]==this) copy[attr] = copy;
          else copy[attr] = this[attr].clone();
          }
          return copy;
          }

          Date.prototype.clone = function() {
          var copy = new Date();
          copy.setTime(this.getTime());
          return copy;
          }

          Number.prototype.clone =
          Boolean.prototype.clone =
          String.prototype.clone = function() {
          return this;
          }


          See also Andy Burke's note in the answers.






          share|improve this answer


























          • Does not work well with inheritance.

            – calbertts
            Jan 2 '14 at 18:52






          • 3





            Date.prototype.clone = function() {return new Date(+this)};

            – RobG
            Dec 2 '14 at 12:20














          21












          21








          21







          A.Levy's answer is almost complete, here is my little contribution: there is a way how to handle recursive references, see this line



          if(this[attr]==this) copy[attr] = copy;



          If the object is XML DOM element, we must use cloneNode instead



          if(this.cloneNode) return this.cloneNode(true);



          Inspired by A.Levy's exhaustive study and Calvin's prototyping approach, I offer this solution:



          Object.prototype.clone = function() {
          if(this.cloneNode) return this.cloneNode(true);
          var copy = this instanceof Array ? : {};
          for(var attr in this) {
          if(typeof this[attr] == "function" || this[attr]==null || !this[attr].clone)
          copy[attr] = this[attr];
          else if(this[attr]==this) copy[attr] = copy;
          else copy[attr] = this[attr].clone();
          }
          return copy;
          }

          Date.prototype.clone = function() {
          var copy = new Date();
          copy.setTime(this.getTime());
          return copy;
          }

          Number.prototype.clone =
          Boolean.prototype.clone =
          String.prototype.clone = function() {
          return this;
          }


          See also Andy Burke's note in the answers.






          share|improve this answer















          A.Levy's answer is almost complete, here is my little contribution: there is a way how to handle recursive references, see this line



          if(this[attr]==this) copy[attr] = copy;



          If the object is XML DOM element, we must use cloneNode instead



          if(this.cloneNode) return this.cloneNode(true);



          Inspired by A.Levy's exhaustive study and Calvin's prototyping approach, I offer this solution:



          Object.prototype.clone = function() {
          if(this.cloneNode) return this.cloneNode(true);
          var copy = this instanceof Array ? : {};
          for(var attr in this) {
          if(typeof this[attr] == "function" || this[attr]==null || !this[attr].clone)
          copy[attr] = this[attr];
          else if(this[attr]==this) copy[attr] = copy;
          else copy[attr] = this[attr].clone();
          }
          return copy;
          }

          Date.prototype.clone = function() {
          var copy = new Date();
          copy.setTime(this.getTime());
          return copy;
          }

          Number.prototype.clone =
          Boolean.prototype.clone =
          String.prototype.clone = function() {
          return this;
          }


          See also Andy Burke's note in the answers.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 2 '12 at 20:49


























          community wiki





          Jan Turoň














          • Does not work well with inheritance.

            – calbertts
            Jan 2 '14 at 18:52






          • 3





            Date.prototype.clone = function() {return new Date(+this)};

            – RobG
            Dec 2 '14 at 12:20



















          • Does not work well with inheritance.

            – calbertts
            Jan 2 '14 at 18:52






          • 3





            Date.prototype.clone = function() {return new Date(+this)};

            – RobG
            Dec 2 '14 at 12:20

















          Does not work well with inheritance.

          – calbertts
          Jan 2 '14 at 18:52





          Does not work well with inheritance.

          – calbertts
          Jan 2 '14 at 18:52




          3




          3





          Date.prototype.clone = function() {return new Date(+this)};

          – RobG
          Dec 2 '14 at 12:20





          Date.prototype.clone = function() {return new Date(+this)};

          – RobG
          Dec 2 '14 at 12:20











          18














          Here is a function you can use.



          function clone(obj) {
          if(obj == null || typeof(obj) != 'object')
          return obj;
          var temp = new obj.constructor();
          for(var key in obj)
          temp[key] = clone(obj[key]);
          return temp;
          }





          share|improve this answer





















          • 8





            This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:21











          • Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

            – james_womack
            Nov 1 '13 at 20:36











          • Upvoted for correctly calling the constructor using new. The accepted answer does not.

            – GetFree
            Jun 14 '15 at 6:29











          • works on node everything else ! still left reference links

            – user956584
            Jul 15 '17 at 22:38
















          18














          Here is a function you can use.



          function clone(obj) {
          if(obj == null || typeof(obj) != 'object')
          return obj;
          var temp = new obj.constructor();
          for(var key in obj)
          temp[key] = clone(obj[key]);
          return temp;
          }





          share|improve this answer





















          • 8





            This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:21











          • Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

            – james_womack
            Nov 1 '13 at 20:36











          • Upvoted for correctly calling the constructor using new. The accepted answer does not.

            – GetFree
            Jun 14 '15 at 6:29











          • works on node everything else ! still left reference links

            – user956584
            Jul 15 '17 at 22:38














          18












          18








          18







          Here is a function you can use.



          function clone(obj) {
          if(obj == null || typeof(obj) != 'object')
          return obj;
          var temp = new obj.constructor();
          for(var key in obj)
          temp[key] = clone(obj[key]);
          return temp;
          }





          share|improve this answer















          Here is a function you can use.



          function clone(obj) {
          if(obj == null || typeof(obj) != 'object')
          return obj;
          var temp = new obj.constructor();
          for(var key in obj)
          temp[key] = clone(obj[key]);
          return temp;
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Feb 23 '12 at 20:04


























          community wiki





          picardo









          • 8





            This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:21











          • Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

            – james_womack
            Nov 1 '13 at 20:36











          • Upvoted for correctly calling the constructor using new. The accepted answer does not.

            – GetFree
            Jun 14 '15 at 6:29











          • works on node everything else ! still left reference links

            – user956584
            Jul 15 '17 at 22:38














          • 8





            This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:21











          • Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

            – james_womack
            Nov 1 '13 at 20:36











          • Upvoted for correctly calling the constructor using new. The accepted answer does not.

            – GetFree
            Jun 14 '15 at 6:29











          • works on node everything else ! still left reference links

            – user956584
            Jul 15 '17 at 22:38








          8




          8





          This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

          – A. Levy
          Apr 8 '09 at 4:21





          This answer is pretty close, but not quite correct. If you try cloning a Date object, you will not get the same date because the call to the Date constructor function initializes the new Date with the current date/time. That value isn't enumerable and won't be copied by the for/in loop.

          – A. Levy
          Apr 8 '09 at 4:21













          Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

          – james_womack
          Nov 1 '13 at 20:36





          Not perfect, but nice for those basic cases. E.g. allowing simple cloning of an argument that can be a basic Object, Array or String.

          – james_womack
          Nov 1 '13 at 20:36













          Upvoted for correctly calling the constructor using new. The accepted answer does not.

          – GetFree
          Jun 14 '15 at 6:29





          Upvoted for correctly calling the constructor using new. The accepted answer does not.

          – GetFree
          Jun 14 '15 at 6:29













          works on node everything else ! still left reference links

          – user956584
          Jul 15 '17 at 22:38





          works on node everything else ! still left reference links

          – user956584
          Jul 15 '17 at 22:38











          18














          From this article: How to copy arrays and objects in Javascript by Brian Huisman:



          Object.prototype.clone = function() {
          var newObj = (this instanceof Array) ? : {};
          for (var i in this) {
          if (i == 'clone') continue;
          if (this[i] && typeof this[i] == "object") {
          newObj[i] = this[i].clone();
          } else newObj[i] = this[i]
          } return newObj;
          };





          share|improve this answer





















          • 4





            This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:17











          • Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

            – iPadDeveloper2011
            Aug 27 '12 at 23:19






          • 3





            @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

            – mikemaccana
            Sep 22 '12 at 22:09






          • 1





            @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

            – mikemaccana
            Oct 1 '12 at 10:54






          • 2





            why isn't var copiedObj = Object.create(obj); a great way as well?

            – Dan P.
            Apr 12 '14 at 20:16
















          18














          From this article: How to copy arrays and objects in Javascript by Brian Huisman:



          Object.prototype.clone = function() {
          var newObj = (this instanceof Array) ? : {};
          for (var i in this) {
          if (i == 'clone') continue;
          if (this[i] && typeof this[i] == "object") {
          newObj[i] = this[i].clone();
          } else newObj[i] = this[i]
          } return newObj;
          };





          share|improve this answer





















          • 4





            This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:17











          • Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

            – iPadDeveloper2011
            Aug 27 '12 at 23:19






          • 3





            @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

            – mikemaccana
            Sep 22 '12 at 22:09






          • 1





            @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

            – mikemaccana
            Oct 1 '12 at 10:54






          • 2





            why isn't var copiedObj = Object.create(obj); a great way as well?

            – Dan P.
            Apr 12 '14 at 20:16














          18












          18








          18







          From this article: How to copy arrays and objects in Javascript by Brian Huisman:



          Object.prototype.clone = function() {
          var newObj = (this instanceof Array) ? : {};
          for (var i in this) {
          if (i == 'clone') continue;
          if (this[i] && typeof this[i] == "object") {
          newObj[i] = this[i].clone();
          } else newObj[i] = this[i]
          } return newObj;
          };





          share|improve this answer















          From this article: How to copy arrays and objects in Javascript by Brian Huisman:



          Object.prototype.clone = function() {
          var newObj = (this instanceof Array) ? : {};
          for (var i in this) {
          if (i == 'clone') continue;
          if (this[i] && typeof this[i] == "object") {
          newObj[i] = this[i].clone();
          } else newObj[i] = this[i]
          } return newObj;
          };






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Sep 22 '12 at 22:06


























          community wiki





          Calvin









          • 4





            This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:17











          • Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

            – iPadDeveloper2011
            Aug 27 '12 at 23:19






          • 3





            @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

            – mikemaccana
            Sep 22 '12 at 22:09






          • 1





            @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

            – mikemaccana
            Oct 1 '12 at 10:54






          • 2





            why isn't var copiedObj = Object.create(obj); a great way as well?

            – Dan P.
            Apr 12 '14 at 20:16














          • 4





            This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

            – A. Levy
            Apr 8 '09 at 4:17











          • Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

            – iPadDeveloper2011
            Aug 27 '12 at 23:19






          • 3





            @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

            – mikemaccana
            Sep 22 '12 at 22:09






          • 1





            @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

            – mikemaccana
            Oct 1 '12 at 10:54






          • 2





            why isn't var copiedObj = Object.create(obj); a great way as well?

            – Dan P.
            Apr 12 '14 at 20:16








          4




          4





          This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

          – A. Levy
          Apr 8 '09 at 4:17





          This is close, but doesn't work for any object. Try cloning a Date object with this. Not all properties are enumerable, so they will not all show up in the for/in loop.

          – A. Levy
          Apr 8 '09 at 4:17













          Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

          – iPadDeveloper2011
          Aug 27 '12 at 23:19





          Adding to the object prototype like this broke jQuery for me. Even when I renamed to clone2.

          – iPadDeveloper2011
          Aug 27 '12 at 23:19




          3




          3





          @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

          – mikemaccana
          Sep 22 '12 at 22:09





          @iPadDeveloper2011 The code above had a bug in it where it created a global variable called 'i' '(for i in this)', rather than '(for var i in this)'. I have enough karma to edit and it and fix it so I did.

          – mikemaccana
          Sep 22 '12 at 22:09




          1




          1





          @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

          – mikemaccana
          Oct 1 '12 at 10:54





          @Calvin: this should be created an a non-enumerable property, otherwise 'clone' will appear in 'for' loops.

          – mikemaccana
          Oct 1 '12 at 10:54




          2




          2





          why isn't var copiedObj = Object.create(obj); a great way as well?

          – Dan P.
          Apr 12 '14 at 20:16





          why isn't var copiedObj = Object.create(obj); a great way as well?

          – Dan P.
          Apr 12 '14 at 20:16











          18














          In ES-6 you can simply use Object.assign(...).
          Ex:



          let obj = {person: 'Thor Odinson'};
          let clone = Object.assign({}, obj);


          A good reference is here:
          https://googlechrome.github.io/samples/object-assign-es6/






          share|improve this answer





















          • 9





            It does not deep clone the object.

            – August
            Jun 1 '17 at 5:31











          • That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

            – HoldOffHunger
            Aug 16 '17 at 16:05











          • @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

            – collapsar
            Sep 1 '17 at 11:00











          • @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

            – HoldOffHunger
            Sep 1 '17 at 11:40













          • @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

            – collapsar
            Sep 1 '17 at 12:50
















          18














          In ES-6 you can simply use Object.assign(...).
          Ex:



          let obj = {person: 'Thor Odinson'};
          let clone = Object.assign({}, obj);


          A good reference is here:
          https://googlechrome.github.io/samples/object-assign-es6/






          share|improve this answer





















          • 9





            It does not deep clone the object.

            – August
            Jun 1 '17 at 5:31











          • That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

            – HoldOffHunger
            Aug 16 '17 at 16:05











          • @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

            – collapsar
            Sep 1 '17 at 11:00











          • @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

            – HoldOffHunger
            Sep 1 '17 at 11:40













          • @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

            – collapsar
            Sep 1 '17 at 12:50














          18












          18








          18







          In ES-6 you can simply use Object.assign(...).
          Ex:



          let obj = {person: 'Thor Odinson'};
          let clone = Object.assign({}, obj);


          A good reference is here:
          https://googlechrome.github.io/samples/object-assign-es6/






          share|improve this answer















          In ES-6 you can simply use Object.assign(...).
          Ex:



          let obj = {person: 'Thor Odinson'};
          let clone = Object.assign({}, obj);


          A good reference is here:
          https://googlechrome.github.io/samples/object-assign-es6/







          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Apr 13 '17 at 20:17


























          community wiki





          João Oliveira









          • 9





            It does not deep clone the object.

            – August
            Jun 1 '17 at 5:31











          • That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

            – HoldOffHunger
            Aug 16 '17 at 16:05











          • @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

            – collapsar
            Sep 1 '17 at 11:00











          • @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

            – HoldOffHunger
            Sep 1 '17 at 11:40













          • @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

            – collapsar
            Sep 1 '17 at 12:50














          • 9





            It does not deep clone the object.

            – August
            Jun 1 '17 at 5:31











          • That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

            – HoldOffHunger
            Aug 16 '17 at 16:05











          • @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

            – collapsar
            Sep 1 '17 at 11:00











          • @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

            – HoldOffHunger
            Sep 1 '17 at 11:40













          • @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

            – collapsar
            Sep 1 '17 at 12:50








          9




          9





          It does not deep clone the object.

          – August
          Jun 1 '17 at 5:31





          It does not deep clone the object.

          – August
          Jun 1 '17 at 5:31













          That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

          – HoldOffHunger
          Aug 16 '17 at 16:05





          That's an assignment, not a copy. clone.Title = "just a clone" means that obj.Title = "just a clone".

          – HoldOffHunger
          Aug 16 '17 at 16:05













          @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

          – collapsar
          Sep 1 '17 at 11:00





          @HoldOffHunger You are mistaken. Check it in your browser's JS console ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)

          – collapsar
          Sep 1 '17 at 11:00













          @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

          – HoldOffHunger
          Sep 1 '17 at 11:40







          @collapsar: That is precisely what I checked, then console.log(person) will be "Whazzup", not "Thor Odinson". See August's comment.

          – HoldOffHunger
          Sep 1 '17 at 11:40















          @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

          – collapsar
          Sep 1 '17 at 12:50





          @HoldOffHunger Does not happen in Chrome 60.0.3112.113 nor in Edge 14.14393; August's comment does not apply as the values of primitive types of obj's properties are indeed cloned. Property values that are Objects themselves will not be cloned.

          – collapsar
          Sep 1 '17 at 12:50











          15














          In ECMAScript 2018



          let objClone = { ...obj };


          Be aware that nested objects are still copied as a reference.






          share|improve this answer


























          • Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

            – Benny Neugebauer
            Jan 2 at 23:32
















          15














          In ECMAScript 2018



          let objClone = { ...obj };


          Be aware that nested objects are still copied as a reference.






          share|improve this answer


























          • Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

            – Benny Neugebauer
            Jan 2 at 23:32














          15












          15








          15







          In ECMAScript 2018



          let objClone = { ...obj };


          Be aware that nested objects are still copied as a reference.






          share|improve this answer















          In ECMAScript 2018



          let objClone = { ...obj };


          Be aware that nested objects are still copied as a reference.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Aug 3 '18 at 16:16


























          community wiki





          2 revs, 2 users 80%
          Pavan Garre














          • Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

            – Benny Neugebauer
            Jan 2 at 23:32



















          • Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

            – Benny Neugebauer
            Jan 2 at 23:32

















          Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

          – Benny Neugebauer
          Jan 2 at 23:32





          Thanks for the hint that nested objects are still copied as a reference! I almost got crazy when debugging my code because I modified nested properties on the "clone" but the original got modified.

          – Benny Neugebauer
          Jan 2 at 23:32











          14














          You can clone an object and remove any reference from the previous one using a single line of code. Simply do:



          var obj1 = { text: 'moo1' };
          var obj2 = Object.create(obj1); // Creates a new clone without references

          obj2.text = 'moo2'; // Only updates obj2's text property

          console.log(obj1, obj2); // Outputs: obj1: {text:'moo1'}, obj2: {text:'moo2'}


          For browsers / engines that do not currently support Object.create you can use this polyfill:



          // Polyfill Object.create if it does not exist
          if (!Object.create) {
          Object.create = function (o) {
          var F = function () {};
          F.prototype = o;
          return new F();
          };
          }





          share|improve this answer





















          • 1





            +1 Object.create(...) seems definitely the way to go.

            – René Nyffenegger
            Jun 30 '14 at 14:49











          • Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

            – froginvasion
            Aug 9 '14 at 12:30











          • Works well but what browsers does the polyfill work in?

            – Ian Lunn
            Oct 9 '14 at 13:25











          • If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

            – Quinthexadec
            Oct 17 '14 at 4:32








          • 8





            This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

            – Nick Desaulniers
            Oct 31 '14 at 21:25
















          14














          You can clone an object and remove any reference from the previous one using a single line of code. Simply do:



          var obj1 = { text: 'moo1' };
          var obj2 = Object.create(obj1); // Creates a new clone without references

          obj2.text = 'moo2'; // Only updates obj2's text property

          console.log(obj1, obj2); // Outputs: obj1: {text:'moo1'}, obj2: {text:'moo2'}


          For browsers / engines that do not currently support Object.create you can use this polyfill:



          // Polyfill Object.create if it does not exist
          if (!Object.create) {
          Object.create = function (o) {
          var F = function () {};
          F.prototype = o;
          return new F();
          };
          }





          share|improve this answer





















          • 1





            +1 Object.create(...) seems definitely the way to go.

            – René Nyffenegger
            Jun 30 '14 at 14:49











          • Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

            – froginvasion
            Aug 9 '14 at 12:30











          • Works well but what browsers does the polyfill work in?

            – Ian Lunn
            Oct 9 '14 at 13:25











          • If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

            – Quinthexadec
            Oct 17 '14 at 4:32








          • 8





            This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

            – Nick Desaulniers
            Oct 31 '14 at 21:25














          14












          14








          14







          You can clone an object and remove any reference from the previous one using a single line of code. Simply do:



          var obj1 = { text: 'moo1' };
          var obj2 = Object.create(obj1); // Creates a new clone without references

          obj2.text = 'moo2'; // Only updates obj2's text property

          console.log(obj1, obj2); // Outputs: obj1: {text:'moo1'}, obj2: {text:'moo2'}


          For browsers / engines that do not currently support Object.create you can use this polyfill:



          // Polyfill Object.create if it does not exist
          if (!Object.create) {
          Object.create = function (o) {
          var F = function () {};
          F.prototype = o;
          return new F();
          };
          }





          share|improve this answer















          You can clone an object and remove any reference from the previous one using a single line of code. Simply do:



          var obj1 = { text: 'moo1' };
          var obj2 = Object.create(obj1); // Creates a new clone without references

          obj2.text = 'moo2'; // Only updates obj2's text property

          console.log(obj1, obj2); // Outputs: obj1: {text:'moo1'}, obj2: {text:'moo2'}


          For browsers / engines that do not currently support Object.create you can use this polyfill:



          // Polyfill Object.create if it does not exist
          if (!Object.create) {
          Object.create = function (o) {
          var F = function () {};
          F.prototype = o;
          return new F();
          };
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Sep 16 '12 at 5:27


























          community wiki





          Rob Evans









          • 1





            +1 Object.create(...) seems definitely the way to go.

            – René Nyffenegger
            Jun 30 '14 at 14:49











          • Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

            – froginvasion
            Aug 9 '14 at 12:30











          • Works well but what browsers does the polyfill work in?

            – Ian Lunn
            Oct 9 '14 at 13:25











          • If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

            – Quinthexadec
            Oct 17 '14 at 4:32








          • 8





            This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

            – Nick Desaulniers
            Oct 31 '14 at 21:25














          • 1





            +1 Object.create(...) seems definitely the way to go.

            – René Nyffenegger
            Jun 30 '14 at 14:49











          • Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

            – froginvasion
            Aug 9 '14 at 12:30











          • Works well but what browsers does the polyfill work in?

            – Ian Lunn
            Oct 9 '14 at 13:25











          • If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

            – Quinthexadec
            Oct 17 '14 at 4:32








          • 8





            This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

            – Nick Desaulniers
            Oct 31 '14 at 21:25








          1




          1





          +1 Object.create(...) seems definitely the way to go.

          – René Nyffenegger
          Jun 30 '14 at 14:49





          +1 Object.create(...) seems definitely the way to go.

          – René Nyffenegger
          Jun 30 '14 at 14:49













          Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

          – froginvasion
          Aug 9 '14 at 12:30





          Perfect answer. Maybe you could add an explanation for Object.hasOwnProperty? That way people know how to prevent searching the prototype link.

          – froginvasion
          Aug 9 '14 at 12:30













          Works well but what browsers does the polyfill work in?

          – Ian Lunn
          Oct 9 '14 at 13:25





          Works well but what browsers does the polyfill work in?

          – Ian Lunn
          Oct 9 '14 at 13:25













          If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

          – Quinthexadec
          Oct 17 '14 at 4:32







          If there are objects or arrays in the original obj1, and they change the objects or arrays in the new obj2, it will be modified obj1's copies because they're stored by reference. Example: ` var obj1 = { thing: {} }; var obj2 = Object.create(obj1); obj2.thing.innerThing = 'test'; console.log(obj1) ` The output will be that obj1 and obj2 are now { thing: { innerThing: "test" } }

          – Quinthexadec
          Oct 17 '14 at 4:32






          8




          8





          This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

          – Nick Desaulniers
          Oct 31 '14 at 21:25





          This is creating obj2 with a obj1 as it's prototype. It only works because you are shadowing the text member in obj2. You are not making a copy, just deferring to the prototype chain when a member is not found on obj2.

          – Nick Desaulniers
          Oct 31 '14 at 21:25











          13














          New answer to an old question! If you have the pleasure of having using ECMAScript 2016 (ES6) with Spread Syntax, it's easy.



          keepMeTheSame = {first: "Me!", second: "You!"};
          cloned = {...keepMeTheSame}


          This provides a clean method for a shallow copy of an object. Making a deep copy, meaning makign a new copy of every value in every recursively nested object, requires on of the heavier solutions above.



          JavaScript keeps evolving.






          share|improve this answer





















          • 1





            it doesn't work when you have functions defined on objects

            – Petr Marek
            Feb 5 '17 at 22:06











          • as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

            – Oleh
            Apr 4 '17 at 8:12













          • @Oleh so use ` {... obj} instead of [...obj];`

            – manikant gautam
            Dec 5 '17 at 6:17













          • @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

            – Oleh
            Dec 6 '17 at 15:11
















          13














          New answer to an old question! If you have the pleasure of having using ECMAScript 2016 (ES6) with Spread Syntax, it's easy.



          keepMeTheSame = {first: "Me!", second: "You!"};
          cloned = {...keepMeTheSame}


          This provides a clean method for a shallow copy of an object. Making a deep copy, meaning makign a new copy of every value in every recursively nested object, requires on of the heavier solutions above.



          JavaScript keeps evolving.






          share|improve this answer





















          • 1





            it doesn't work when you have functions defined on objects

            – Petr Marek
            Feb 5 '17 at 22:06











          • as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

            – Oleh
            Apr 4 '17 at 8:12













          • @Oleh so use ` {... obj} instead of [...obj];`

            – manikant gautam
            Dec 5 '17 at 6:17













          • @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

            – Oleh
            Dec 6 '17 at 15:11














          13












          13








          13







          New answer to an old question! If you have the pleasure of having using ECMAScript 2016 (ES6) with Spread Syntax, it's easy.



          keepMeTheSame = {first: "Me!", second: "You!"};
          cloned = {...keepMeTheSame}


          This provides a clean method for a shallow copy of an object. Making a deep copy, meaning makign a new copy of every value in every recursively nested object, requires on of the heavier solutions above.



          JavaScript keeps evolving.






          share|improve this answer















          New answer to an old question! If you have the pleasure of having using ECMAScript 2016 (ES6) with Spread Syntax, it's easy.



          keepMeTheSame = {first: "Me!", second: "You!"};
          cloned = {...keepMeTheSame}


          This provides a clean method for a shallow copy of an object. Making a deep copy, meaning makign a new copy of every value in every recursively nested object, requires on of the heavier solutions above.



          JavaScript keeps evolving.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Dec 16 '16 at 11:34


























          community wiki





          Charles Merriam









          • 1





            it doesn't work when you have functions defined on objects

            – Petr Marek
            Feb 5 '17 at 22:06











          • as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

            – Oleh
            Apr 4 '17 at 8:12













          • @Oleh so use ` {... obj} instead of [...obj];`

            – manikant gautam
            Dec 5 '17 at 6:17













          • @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

            – Oleh
            Dec 6 '17 at 15:11














          • 1





            it doesn't work when you have functions defined on objects

            – Petr Marek
            Feb 5 '17 at 22:06











          • as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

            – Oleh
            Apr 4 '17 at 8:12













          • @Oleh so use ` {... obj} instead of [...obj];`

            – manikant gautam
            Dec 5 '17 at 6:17













          • @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

            – Oleh
            Dec 6 '17 at 15:11








          1




          1





          it doesn't work when you have functions defined on objects

          – Petr Marek
          Feb 5 '17 at 22:06





          it doesn't work when you have functions defined on objects

          – Petr Marek
          Feb 5 '17 at 22:06













          as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

          – Oleh
          Apr 4 '17 at 8:12







          as far as I see spread operator only works with iterables - developer.mozilla.org says: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable

          – Oleh
          Apr 4 '17 at 8:12















          @Oleh so use ` {... obj} instead of [...obj];`

          – manikant gautam
          Dec 5 '17 at 6:17







          @Oleh so use ` {... obj} instead of [...obj];`

          – manikant gautam
          Dec 5 '17 at 6:17















          @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

          – Oleh
          Dec 6 '17 at 15:11





          @manikantgautam I was using Object.assign() before, but now indeed object spread syntax is supported in latest Chrome, Firefox (still not in Edge and Safari). Its ECMAScript proposal... but Babel does support it as far as I can see, so probably its safe to use.

          – Oleh
          Dec 6 '17 at 15:11











          10














          Using Lodash:



          var y = _.clone(x, true);





          share|improve this answer





















          • 3





            OMG it would be insane to reinvent cloning. This is the only sane answer.

            – Dan Ross
            Sep 11 '13 at 8:48






          • 4





            I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

            – garbanzio
            Dec 18 '14 at 19:40











          • @DanRoss true that

            – Fahmi
            Apr 15 '17 at 11:29
















          10














          Using Lodash:



          var y = _.clone(x, true);





          share|improve this answer





















          • 3





            OMG it would be insane to reinvent cloning. This is the only sane answer.

            – Dan Ross
            Sep 11 '13 at 8:48






          • 4





            I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

            – garbanzio
            Dec 18 '14 at 19:40











          • @DanRoss true that

            – Fahmi
            Apr 15 '17 at 11:29














          10












          10








          10







          Using Lodash:



          var y = _.clone(x, true);





          share|improve this answer















          Using Lodash:



          var y = _.clone(x, true);






          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered Dec 13 '12 at 0:05


























          community wiki





          VaZaA









          • 3





            OMG it would be insane to reinvent cloning. This is the only sane answer.

            – Dan Ross
            Sep 11 '13 at 8:48






          • 4





            I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

            – garbanzio
            Dec 18 '14 at 19:40











          • @DanRoss true that

            – Fahmi
            Apr 15 '17 at 11:29














          • 3





            OMG it would be insane to reinvent cloning. This is the only sane answer.

            – Dan Ross
            Sep 11 '13 at 8:48






          • 4





            I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

            – garbanzio
            Dec 18 '14 at 19:40











          • @DanRoss true that

            – Fahmi
            Apr 15 '17 at 11:29








          3




          3





          OMG it would be insane to reinvent cloning. This is the only sane answer.

          – Dan Ross
          Sep 11 '13 at 8:48





          OMG it would be insane to reinvent cloning. This is the only sane answer.

          – Dan Ross
          Sep 11 '13 at 8:48




          4




          4





          I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

          – garbanzio
          Dec 18 '14 at 19:40





          I prefer _.cloneDeep(x) as it essentially is the same thing as above, but reads better.

          – garbanzio
          Dec 18 '14 at 19:40













          @DanRoss true that

          – Fahmi
          Apr 15 '17 at 11:29





          @DanRoss true that

          – Fahmi
          Apr 15 '17 at 11:29











          10














          let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)


          ES6 solution if you want to (shallow) clone a class instance and not just a property object.






          share|improve this answer






























            10














            let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)


            ES6 solution if you want to (shallow) clone a class instance and not just a property object.






            share|improve this answer




























              10












              10








              10







              let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)


              ES6 solution if you want to (shallow) clone a class instance and not just a property object.






              share|improve this answer















              let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)


              ES6 solution if you want to (shallow) clone a class instance and not just a property object.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jun 27 '17 at 12:57


























              community wiki





              3 revs
              flori
























                  9














                  Interested in cloning simple objects :



                  JSON.parse(JSON.stringify(json_original));



                  Source : How to copy JavaScript object to new variable NOT by reference?






                  share|improve this answer






























                    9














                    Interested in cloning simple objects :



                    JSON.parse(JSON.stringify(json_original));



                    Source : How to copy JavaScript object to new variable NOT by reference?






                    share|improve this answer




























                      9












                      9








                      9







                      Interested in cloning simple objects :



                      JSON.parse(JSON.stringify(json_original));



                      Source : How to copy JavaScript object to new variable NOT by reference?






                      share|improve this answer















                      Interested in cloning simple objects :



                      JSON.parse(JSON.stringify(json_original));



                      Source : How to copy JavaScript object to new variable NOT by reference?







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited May 23 '17 at 12:18


























                      community wiki





                      2 revs
                      Mohammed Akdim
























                          8














                          I think there is a simple and working answer. In deep copying there are two concerns:




                          1. Keep properties dependent of each other.

                          2. And keep the methods alive on cloned object.


                          So I think one simple solution will be to first serialize and deserialize and then do an assign on it to copy functions too.



                          let deepCloned = JSON.parse(JSON.stringify(source));
                          let merged = Object.assign({}, source);
                          Object.assign(merged, deepCloned);


                          Although this question has many answers, I hope this one helps too.






                          share|improve this answer


























                          • Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

                            – ConductedClever
                            Jan 13 at 6:01






                          • 1





                            I'm using JSON.parse(JSON.stringify(source)). Always working.

                            – Misha
                            Feb 22 at 15:50











                          • @Misha, this way you will miss the functions. The term 'works' has many meanings.

                            – ConductedClever
                            Feb 23 at 5:26











                          • And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

                            – ConductedClever
                            Feb 23 at 5:29
















                          8














                          I think there is a simple and working answer. In deep copying there are two concerns:




                          1. Keep properties dependent of each other.

                          2. And keep the methods alive on cloned object.


                          So I think one simple solution will be to first serialize and deserialize and then do an assign on it to copy functions too.



                          let deepCloned = JSON.parse(JSON.stringify(source));
                          let merged = Object.assign({}, source);
                          Object.assign(merged, deepCloned);


                          Although this question has many answers, I hope this one helps too.






                          share|improve this answer


























                          • Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

                            – ConductedClever
                            Jan 13 at 6:01






                          • 1





                            I'm using JSON.parse(JSON.stringify(source)). Always working.

                            – Misha
                            Feb 22 at 15:50











                          • @Misha, this way you will miss the functions. The term 'works' has many meanings.

                            – ConductedClever
                            Feb 23 at 5:26











                          • And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

                            – ConductedClever
                            Feb 23 at 5:29














                          8












                          8








                          8







                          I think there is a simple and working answer. In deep copying there are two concerns:




                          1. Keep properties dependent of each other.

                          2. And keep the methods alive on cloned object.


                          So I think one simple solution will be to first serialize and deserialize and then do an assign on it to copy functions too.



                          let deepCloned = JSON.parse(JSON.stringify(source));
                          let merged = Object.assign({}, source);
                          Object.assign(merged, deepCloned);


                          Although this question has many answers, I hope this one helps too.






                          share|improve this answer















                          I think there is a simple and working answer. In deep copying there are two concerns:




                          1. Keep properties dependent of each other.

                          2. And keep the methods alive on cloned object.


                          So I think one simple solution will be to first serialize and deserialize and then do an assign on it to copy functions too.



                          let deepCloned = JSON.parse(JSON.stringify(source));
                          let merged = Object.assign({}, source);
                          Object.assign(merged, deepCloned);


                          Although this question has many answers, I hope this one helps too.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Jan 13 at 5:38


























                          community wiki





                          2 revs
                          ConductedClever














                          • Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

                            – ConductedClever
                            Jan 13 at 6:01






                          • 1





                            I'm using JSON.parse(JSON.stringify(source)). Always working.

                            – Misha
                            Feb 22 at 15:50











                          • @Misha, this way you will miss the functions. The term 'works' has many meanings.

                            – ConductedClever
                            Feb 23 at 5:26











                          • And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

                            – ConductedClever
                            Feb 23 at 5:29



















                          • Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

                            – ConductedClever
                            Jan 13 at 6:01






                          • 1





                            I'm using JSON.parse(JSON.stringify(source)). Always working.

                            – Misha
                            Feb 22 at 15:50











                          • @Misha, this way you will miss the functions. The term 'works' has many meanings.

                            – ConductedClever
                            Feb 23 at 5:26











                          • And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

                            – ConductedClever
                            Feb 23 at 5:29

















                          Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

                          – ConductedClever
                          Jan 13 at 6:01





                          Although if I am permitted to import lodash, I prefer using lodash cloneDeep.

                          – ConductedClever
                          Jan 13 at 6:01




                          1




                          1





                          I'm using JSON.parse(JSON.stringify(source)). Always working.

                          – Misha
                          Feb 22 at 15:50





                          I'm using JSON.parse(JSON.stringify(source)). Always working.

                          – Misha
                          Feb 22 at 15:50













                          @Misha, this way you will miss the functions. The term 'works' has many meanings.

                          – ConductedClever
                          Feb 23 at 5:26





                          @Misha, this way you will miss the functions. The term 'works' has many meanings.

                          – ConductedClever
                          Feb 23 at 5:26













                          And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

                          – ConductedClever
                          Feb 23 at 5:29





                          And keep in mind that, the way I have mentioned, only the functions of the first layer will be copied. So If we have some objects inside each other, then the only way is to copy field by field recursively.

                          – ConductedClever
                          Feb 23 at 5:29











                          6














                          Jan Turoň's answer above is very close, and may be the best to use in a browser due to compatibility issues, but it will potentially cause some strange enumeration issues. For instance, executing:



                          for ( var i in someArray ) { ... }


                          Will assign the clone() method to i after iterating through the elements of the array. Here's an adaptation that avoids the enumeration and works with node.js:



                          Object.defineProperty( Object.prototype, "clone", {
                          value: function() {
                          if ( this.cloneNode )
                          {
                          return this.cloneNode( true );
                          }

                          var copy = this instanceof Array ? : {};
                          for( var attr in this )
                          {
                          if ( typeof this[ attr ] == "function" || this[ attr ] == null || !this[ attr ].clone )
                          {
                          copy[ attr ] = this[ attr ];
                          }
                          else if ( this[ attr ] == this )
                          {
                          copy[ attr ] = copy;
                          }
                          else
                          {
                          copy[ attr ] = this[ attr ].clone();
                          }
                          }
                          return copy;
                          }
                          });

                          Object.defineProperty( Date.prototype, "clone", {
                          value: function() {
                          var copy = new Date();
                          copy.setTime( this.getTime() );
                          return copy;
                          }
                          });

                          Object.defineProperty( Number.prototype, "clone", { value: function() { return this; } } );
                          Object.defineProperty( Boolean.prototype, "clone", { value: function() { return this; } } );
                          Object.defineProperty( String.prototype, "clone", { value: function() { return this; } } );


                          This avoids making the clone() method enumerable because defineProperty() defaults enumerable to false.






                          share|improve this answer






























                            6














                            Jan Turoň's answer above is very close, and may be the best to use in a browser due to compatibility issues, but it will potentially cause some strange enumeration issues. For instance, executing:



                            for ( var i in someArray ) { ... }


                            Will assign the clone() method to i after iterating through the elements of the array. Here's an adaptation that avoids the enumeration and works with node.js:



                            Object.defineProperty( Object.prototype, "clone", {
                            value: function() {
                            if ( this.cloneNode )
                            {
                            return this.cloneNode( true );
                            }

                            var copy = this instanceof Array ? : {};
                            for( var attr in this )
                            {
                            if ( typeof this[ attr ] == "function" || this[ attr ] == null || !this[ attr ].clone )
                            {
                            copy[ attr ] = this[ attr ];
                            }
                            else if ( this[ attr ] == this )
                            {
                            copy[ attr ] = copy;
                            }
                            else
                            {
                            copy[ attr ] = this[ attr ].clone();
                            }
                            }
                            return copy;
                            }
                            });

                            Object.defineProperty( Date.prototype, "clone", {
                            value: function() {
                            var copy = new Date();
                            copy.setTime( this.getTime() );
                            return copy;
                            }
                            });

                            Object.defineProperty( Number.prototype, "clone", { value: function() { return this; } } );
                            Object.defineProperty( Boolean.prototype, "clone", { value: function() { return this; } } );
                            Object.defineProperty( String.prototype, "clone", { value: function() { return this; } } );


                            This avoids making the clone() method enumerable because defineProperty() defaults enumerable to false.






                            share|improve this answer




























                              6












                              6








                              6







                              Jan Turoň's answer above is very close, and may be the best to use in a browser due to compatibility issues, but it will potentially cause some strange enumeration issues. For instance, executing:



                              for ( var i in someArray ) { ... }


                              Will assign the clone() method to i after iterating through the elements of the array. Here's an adaptation that avoids the enumeration and works with node.js:



                              Object.defineProperty( Object.prototype, "clone", {
                              value: function() {
                              if ( this.cloneNode )
                              {
                              return this.cloneNode( true );
                              }

                              var copy = this instanceof Array ? : {};
                              for( var attr in this )
                              {
                              if ( typeof this[ attr ] == "function" || this[ attr ] == null || !this[ attr ].clone )
                              {
                              copy[ attr ] = this[ attr ];
                              }
                              else if ( this[ attr ] == this )
                              {
                              copy[ attr ] = copy;
                              }
                              else
                              {
                              copy[ attr ] = this[ attr ].clone();
                              }
                              }
                              return copy;
                              }
                              });

                              Object.defineProperty( Date.prototype, "clone", {
                              value: function() {
                              var copy = new Date();
                              copy.setTime( this.getTime() );
                              return copy;
                              }
                              });

                              Object.defineProperty( Number.prototype, "clone", { value: function() { return this; } } );
                              Object.defineProperty( Boolean.prototype, "clone", { value: function() { return this; } } );
                              Object.defineProperty( String.prototype, "clone", { value: function() { return this; } } );


                              This avoids making the clone() method enumerable because defineProperty() defaults enumerable to false.






                              share|improve this answer















                              Jan Turoň's answer above is very close, and may be the best to use in a browser due to compatibility issues, but it will potentially cause some strange enumeration issues. For instance, executing:



                              for ( var i in someArray ) { ... }


                              Will assign the clone() method to i after iterating through the elements of the array. Here's an adaptation that avoids the enumeration and works with node.js:



                              Object.defineProperty( Object.prototype, "clone", {
                              value: function() {
                              if ( this.cloneNode )
                              {
                              return this.cloneNode( true );
                              }

                              var copy = this instanceof Array ? : {};
                              for( var attr in this )
                              {
                              if ( typeof this[ attr ] == "function" || this[ attr ] == null || !this[ attr ].clone )
                              {
                              copy[ attr ] = this[ attr ];
                              }
                              else if ( this[ attr ] == this )
                              {
                              copy[ attr ] = copy;
                              }
                              else
                              {
                              copy[ attr ] = this[ attr ].clone();
                              }
                              }
                              return copy;
                              }
                              });

                              Object.defineProperty( Date.prototype, "clone", {
                              value: function() {
                              var copy = new Date();
                              copy.setTime( this.getTime() );
                              return copy;
                              }
                              });

                              Object.defineProperty( Number.prototype, "clone", { value: function() { return this; } } );
                              Object.defineProperty( Boolean.prototype, "clone", { value: function() { return this; } } );
                              Object.defineProperty( String.prototype, "clone", { value: function() { return this; } } );


                              This avoids making the clone() method enumerable because defineProperty() defaults enumerable to false.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              answered Mar 30 '12 at 6:03


























                              community wiki





                              Andy Burke
























                                  6














                                  This is an adaptation of A. Levy's code to also handle the cloning of functions and multiple/cyclic references - what this means is that if two properties in the tree which is cloned are references of the same object, the cloned object tree will have these properties point to one and the same clone of the referenced object. This also solves the case of cyclic dependencies which, if left unhandled, leads to an infinite loop. The complexity of the algorithm is O(n)



                                  function clone(obj){
                                  var clonedObjectsArray = ;
                                  var originalObjectsArray = ; //used to remove the unique ids when finished
                                  var next_objid = 0;

                                  function objectId(obj) {
                                  if (obj == null) return null;
                                  if (obj.__obj_id == undefined){
                                  obj.__obj_id = next_objid++;
                                  originalObjectsArray[obj.__obj_id] = obj;
                                  }
                                  return obj.__obj_id;
                                  }

                                  function cloneRecursive(obj) {
                                  if (null == obj || typeof obj == "string" || typeof obj == "number" || typeof obj == "boolean") return obj;

                                  // Handle Date
                                  if (obj instanceof Date) {
                                  var copy = new Date();
                                  copy.setTime(obj.getTime());
                                  return copy;
                                  }

                                  // Handle Array
                                  if (obj instanceof Array) {
                                  var copy = ;
                                  for (var i = 0; i < obj.length; ++i) {
                                  copy[i] = cloneRecursive(obj[i]);
                                  }
                                  return copy;
                                  }

                                  // Handle Object
                                  if (obj instanceof Object) {
                                  if (clonedObjectsArray[objectId(obj)] != undefined)
                                  return clonedObjectsArray[objectId(obj)];

                                  var copy;
                                  if (obj instanceof Function)//Handle Function
                                  copy = function(){return obj.apply(this, arguments);};
                                  else
                                  copy = {};

                                  clonedObjectsArray[objectId(obj)] = copy;

                                  for (var attr in obj)
                                  if (attr != "__obj_id" && obj.hasOwnProperty(attr))
                                  copy[attr] = cloneRecursive(obj[attr]);

                                  return copy;
                                  }


                                  throw new Error("Unable to copy obj! Its type isn't supported.");
                                  }
                                  var cloneObj = cloneRecursive(obj);



                                  //remove the unique ids
                                  for (var i = 0; i < originalObjectsArray.length; i++)
                                  {
                                  delete originalObjectsArray[i].__obj_id;
                                  };

                                  return cloneObj;
                                  }


                                  Some quick tests



                                  var auxobj = {
                                  prop1 : "prop1 aux val",
                                  prop2 : ["prop2 item1", "prop2 item2"]
                                  };

                                  var obj = new Object();
                                  obj.prop1 = "prop1_value";
                                  obj.prop2 = [auxobj, auxobj, "some extra val", undefined];
                                  obj.nr = 3465;
                                  obj.bool = true;

                                  obj.f1 = function (){
                                  this.prop1 = "prop1 val changed by f1";
                                  };

                                  objclone = clone(obj);

                                  //some tests i've made
                                  console.log("test number, boolean and string cloning: " + (objclone.prop1 == obj.prop1 && objclone.nr == obj.nr && objclone.bool == obj.bool));

                                  objclone.f1();
                                  console.log("test function cloning 1: " + (objclone.prop1 == 'prop1 val changed by f1'));
                                  objclone.f1.prop = 'some prop';
                                  console.log("test function cloning 2: " + (obj.f1.prop == undefined));

                                  objclone.prop2[0].prop1 = "prop1 aux val NEW";
                                  console.log("test multiple references cloning 1: " + (objclone.prop2[1].prop1 == objclone.prop2[0].prop1));
                                  console.log("test multiple references cloning 2: " + (objclone.prop2[1].prop1 != obj.prop2[0].prop1));





                                  share|improve this answer





















                                  • 1





                                    As of September 2016, this is the only correct solution to the question.

                                    – DomQ
                                    Sep 27 '16 at 20:18











                                  • well, thanks. feel free to vote it then

                                    – Radu Simionescu
                                    Sep 28 '16 at 17:58
















                                  6














                                  This is an adaptation of A. Levy's code to also handle the cloning of functions and multiple/cyclic references - what this means is that if two properties in the tree which is cloned are references of the same object, the cloned object tree will have these properties point to one and the same clone of the referenced object. This also solves the case of cyclic dependencies which, if left unhandled, leads to an infinite loop. The complexity of the algorithm is O(n)



                                  function clone(obj){
                                  var clonedObjectsArray = ;
                                  var originalObjectsArray = ; //used to remove the unique ids when finished
                                  var next_objid = 0;

                                  function objectId(obj) {
                                  if (obj == null) return null;
                                  if (obj.__obj_id == undefined){
                                  obj.__obj_id = next_objid++;
                                  originalObjectsArray[obj.__obj_id] = obj;
                                  }
                                  return obj.__obj_id;
                                  }

                                  function cloneRecursive(obj) {
                                  if (null == obj || typeof obj == "string" || typeof obj == "number" || typeof obj == "boolean") return obj;

                                  // Handle Date
                                  if (obj instanceof Date) {
                                  var copy = new Date();
                                  copy.setTime(obj.getTime());
                                  return copy;
                                  }

                                  // Handle Array
                                  if (obj instanceof Array) {
                                  var copy = ;
                                  for (var i = 0; i < obj.length; ++i) {
                                  copy[i] = cloneRecursive(obj[i]);
                                  }
                                  return copy;
                                  }

                                  // Handle Object
                                  if (obj instanceof Object) {
                                  if (clonedObjectsArray[objectId(obj)] != undefined)
                                  return clonedObjectsArray[objectId(obj)];

                                  var copy;
                                  if (obj instanceof Function)//Handle Function
                                  copy = function(){return obj.apply(this, arguments);};
                                  else
                                  copy = {};

                                  clonedObjectsArray[objectId(obj)] = copy;

                                  for (var attr in obj)
                                  if (attr != "__obj_id" && obj.hasOwnProperty(attr))
                                  copy[attr] = cloneRecursive(obj[attr]);

                                  return copy;
                                  }


                                  throw new Error("Unable to copy obj! Its type isn't supported.");
                                  }
                                  var cloneObj = cloneRecursive(obj);



                                  //remove the unique ids
                                  for (var i = 0; i < originalObjectsArray.length; i++)
                                  {
                                  delete originalObjectsArray[i].__obj_id;
                                  };

                                  return cloneObj;
                                  }


                                  Some quick tests



                                  var auxobj = {
                                  prop1 : "prop1 aux val",
                                  prop2 : ["prop2 item1", "prop2 item2"]
                                  };

                                  var obj = new Object();
                                  obj.prop1 = "prop1_value";
                                  obj.prop2 = [auxobj, auxobj, "some extra val", undefined];
                                  obj.nr = 3465;
                                  obj.bool = true;

                                  obj.f1 = function (){
                                  this.prop1 = "prop1 val changed by f1";
                                  };

                                  objclone = clone(obj);

                                  //some tests i've made
                                  console.log("test number, boolean and string cloning: " + (objclone.prop1 == obj.prop1 && objclone.nr == obj.nr && objclone.bool == obj.bool));

                                  objclone.f1();
                                  console.log("test function cloning 1: " + (objclone.prop1 == 'prop1 val changed by f1'));
                                  objclone.f1.prop = 'some prop';
                                  console.log("test function cloning 2: " + (obj.f1.prop == undefined));

                                  objclone.prop2[0].prop1 = "prop1 aux val NEW";
                                  console.log("test multiple references cloning 1: " + (objclone.prop2[1].prop1 == objclone.prop2[0].prop1));
                                  console.log("test multiple references cloning 2: " + (objclone.prop2[1].prop1 != obj.prop2[0].prop1));





                                  share|improve this answer





















                                  • 1





                                    As of September 2016, this is the only correct solution to the question.

                                    – DomQ
                                    Sep 27 '16 at 20:18











                                  • well, thanks. feel free to vote it then

                                    – Radu Simionescu
                                    Sep 28 '16 at 17:58














                                  6












                                  6








                                  6







                                  This is an adaptation of A. Levy's code to also handle the cloning of functions and multiple/cyclic references - what this means is that if two properties in the tree which is cloned are references of the same object, the cloned object tree will have these properties point to one and the same clone of the referenced object. This also solves the case of cyclic dependencies which, if left unhandled, leads to an infinite loop. The complexity of the algorithm is O(n)



                                  function clone(obj){
                                  var clonedObjectsArray = ;
                                  var originalObjectsArray = ; //used to remove the unique ids when finished
                                  var next_objid = 0;

                                  function objectId(obj) {
                                  if (obj == null) return null;
                                  if (obj.__obj_id == undefined){
                                  obj.__obj_id = next_objid++;
                                  originalObjectsArray[obj.__obj_id] = obj;
                                  }
                                  return obj.__obj_id;
                                  }

                                  function cloneRecursive(obj) {
                                  if (null == obj || typeof obj == "string" || typeof obj == "number" || typeof obj == "boolean") return obj;

                                  // Handle Date
                                  if (obj instanceof Date) {
                                  var copy = new Date();
                                  copy.setTime(obj.getTime());
                                  return copy;
                                  }

                                  // Handle Array
                                  if (obj instanceof Array) {
                                  var copy = ;
                                  for (var i = 0; i < obj.length; ++i) {
                                  copy[i] = cloneRecursive(obj[i]);
                                  }
                                  return copy;
                                  }

                                  // Handle Object
                                  if (obj instanceof Object) {
                                  if (clonedObjectsArray[objectId(obj)] != undefined)
                                  return clonedObjectsArray[objectId(obj)];

                                  var copy;
                                  if (obj instanceof Function)//Handle Function
                                  copy = function(){return obj.apply(this, arguments);};
                                  else
                                  copy = {};

                                  clonedObjectsArray[objectId(obj)] = copy;

                                  for (var attr in obj)
                                  if (attr != "__obj_id" && obj.hasOwnProperty(attr))
                                  copy[attr] = cloneRecursive(obj[attr]);

                                  return copy;
                                  }


                                  throw new Error("Unable to copy obj! Its type isn't supported.");
                                  }
                                  var cloneObj = cloneRecursive(obj);



                                  //remove the unique ids
                                  for (var i = 0; i < originalObjectsArray.length; i++)
                                  {
                                  delete originalObjectsArray[i].__obj_id;
                                  };

                                  return cloneObj;
                                  }


                                  Some quick tests



                                  var auxobj = {
                                  prop1 : "prop1 aux val",
                                  prop2 : ["prop2 item1", "prop2 item2"]
                                  };

                                  var obj = new Object();
                                  obj.prop1 = "prop1_value";
                                  obj.prop2 = [auxobj, auxobj, "some extra val", undefined];
                                  obj.nr = 3465;
                                  obj.bool = true;

                                  obj.f1 = function (){
                                  this.prop1 = "prop1 val changed by f1";
                                  };

                                  objclone = clone(obj);

                                  //some tests i've made
                                  console.log("test number, boolean and string cloning: " + (objclone.prop1 == obj.prop1 && objclone.nr == obj.nr && objclone.bool == obj.bool));

                                  objclone.f1();
                                  console.log("test function cloning 1: " + (objclone.prop1 == 'prop1 val changed by f1'));
                                  objclone.f1.prop = 'some prop';
                                  console.log("test function cloning 2: " + (obj.f1.prop == undefined));

                                  objclone.prop2[0].prop1 = "prop1 aux val NEW";
                                  console.log("test multiple references cloning 1: " + (objclone.prop2[1].prop1 == objclone.prop2[0].prop1));
                                  console.log("test multiple references cloning 2: " + (objclone.prop2[1].prop1 != obj.prop2[0].prop1));





                                  share|improve this answer















                                  This is an adaptation of A. Levy's code to also handle the cloning of functions and multiple/cyclic references - what this means is that if two properties in the tree which is cloned are references of the same object, the cloned object tree will have these properties point to one and the same clone of the referenced object. This also solves the case of cyclic dependencies which, if left unhandled, leads to an infinite loop. The complexity of the algorithm is O(n)



                                  function clone(obj){
                                  var clonedObjectsArray = ;
                                  var originalObjectsArray = ; //used to remove the unique ids when finished
                                  var next_objid = 0;

                                  function objectId(obj) {
                                  if (obj == null) return null;
                                  if (obj.__obj_id == undefined){
                                  obj.__obj_id = next_objid++;
                                  originalObjectsArray[obj.__obj_id] = obj;
                                  }
                                  return obj.__obj_id;
                                  }

                                  function cloneRecursive(obj) {
                                  if (null == obj || typeof obj == "string" || typeof obj == "number" || typeof obj == "boolean") return obj;

                                  // Handle Date
                                  if (obj instanceof Date) {
                                  var copy = new Date();
                                  copy.setTime(obj.getTime());
                                  return copy;
                                  }

                                  // Handle Array
                                  if (obj instanceof Array) {
                                  var copy = ;
                                  for (var i = 0; i < obj.length; ++i) {
                                  copy[i] = cloneRecursive(obj[i]);
                                  }
                                  return copy;
                                  }

                                  // Handle Object
                                  if (obj instanceof Object) {
                                  if (clonedObjectsArray[objectId(obj)] != undefined)
                                  return clonedObjectsArray[objectId(obj)];

                                  var copy;
                                  if (obj instanceof Function)//Handle Function
                                  copy = function(){return obj.apply(this, arguments);};
                                  else
                                  copy = {};

                                  clonedObjectsArray[objectId(obj)] = copy;

                                  for (var attr in obj)
                                  if (attr != "__obj_id" && obj.hasOwnProperty(attr))
                                  copy[attr] = cloneRecursive(obj[attr]);

                                  return copy;
                                  }


                                  throw new Error("Unable to copy obj! Its type isn't supported.");
                                  }
                                  var cloneObj = cloneRecursive(obj);



                                  //remove the unique ids
                                  for (var i = 0; i < originalObjectsArray.length; i++)
                                  {
                                  delete originalObjectsArray[i].__obj_id;
                                  };

                                  return cloneObj;
                                  }


                                  Some quick tests



                                  var auxobj = {
                                  prop1 : "prop1 aux val",
                                  prop2 : ["prop2 item1", "prop2 item2"]
                                  };

                                  var obj = new Object();
                                  obj.prop1 = "prop1_value";
                                  obj.prop2 = [auxobj, auxobj, "some extra val", undefined];
                                  obj.nr = 3465;
                                  obj.bool = true;

                                  obj.f1 = function (){
                                  this.prop1 = "prop1 val changed by f1";
                                  };

                                  objclone = clone(obj);

                                  //some tests i've made
                                  console.log("test number, boolean and string cloning: " + (objclone.prop1 == obj.prop1 && objclone.nr == obj.nr && objclone.bool == obj.bool));

                                  objclone.f1();
                                  console.log("test function cloning 1: " + (objclone.prop1 == 'prop1 val changed by f1'));
                                  objclone.f1.prop = 'some prop';
                                  console.log("test function cloning 2: " + (obj.f1.prop == undefined));

                                  objclone.prop2[0].prop1 = "prop1 aux val NEW";
                                  console.log("test multiple references cloning 1: " + (objclone.prop2[1].prop1 == objclone.prop2[0].prop1));
                                  console.log("test multiple references cloning 2: " + (objclone.prop2[1].prop1 != obj.prop2[0].prop1));






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Jul 16 '12 at 9:23


























                                  community wiki





                                  Radu Simionescu









                                  • 1





                                    As of September 2016, this is the only correct solution to the question.

                                    – DomQ
                                    Sep 27 '16 at 20:18











                                  • well, thanks. feel free to vote it then

                                    – Radu Simionescu
                                    Sep 28 '16 at 17:58














                                  • 1





                                    As of September 2016, this is the only correct solution to the question.

                                    – DomQ
                                    Sep 27 '16 at 20:18











                                  • well, thanks. feel free to vote it then

                                    – Radu Simionescu
                                    Sep 28 '16 at 17:58








                                  1




                                  1





                                  As of September 2016, this is the only correct solution to the question.

                                  – DomQ
                                  Sep 27 '16 at 20:18





                                  As of September 2016, this is the only correct solution to the question.

                                  – DomQ
                                  Sep 27 '16 at 20:18













                                  well, thanks. feel free to vote it then

                                  – Radu Simionescu
                                  Sep 28 '16 at 17:58





                                  well, thanks. feel free to vote it then

                                  – Radu Simionescu
                                  Sep 28 '16 at 17:58











                                  6














                                  function clone(src, deep) {

                                  var toString = Object.prototype.toString;
                                  if(!src && typeof src != "object"){
                                  //any non-object ( Boolean, String, Number ), null, undefined, NaN
                                  return src;
                                  }

                                  //Honor native/custom clone methods
                                  if(src.clone && toString.call(src.clone) == "[object Function]"){
                                  return src.clone(deep);
                                  }

                                  //DOM Elements
                                  if(src.nodeType && toString.call(src.cloneNode) == "[object Function]"){
                                  return src.cloneNode(deep);
                                  }

                                  //Date
                                  if(toString.call(src) == "[object Date]"){
                                  return new Date(src.getTime());
                                  }

                                  //RegExp
                                  if(toString.call(src) == "[object RegExp]"){
                                  return new RegExp(src);
                                  }

                                  //Function
                                  if(toString.call(src) == "[object Function]"){
                                  //Wrap in another method to make sure == is not true;
                                  //Note: Huge performance issue due to closures, comment this :)
                                  return (function(){
                                  src.apply(this, arguments);
                                  });

                                  }

                                  var ret, index;
                                  //Array
                                  if(toString.call(src) == "[object Array]"){
                                  //.slice(0) would soft clone
                                  ret = src.slice();
                                  if(deep){
                                  index = ret.length;
                                  while(index--){
                                  ret[index] = clone(ret[index], true);
                                  }
                                  }
                                  }
                                  //Object
                                  else {
                                  ret = src.constructor ? new src.constructor() : {};
                                  for (var prop in src) {
                                  ret[prop] = deep
                                  ? clone(src[prop], true)
                                  : src[prop];
                                  }
                                  }

                                  return ret;
                                  };





                                  share|improve this answer


























                                  • Did this solution help you ? Let me know if u see any issues.

                                    – user1547016
                                    Aug 1 '12 at 17:00






                                  • 2





                                    if(!src && typeof src != "object"){. I think that should be || not &&.

                                    – MikeM
                                    Apr 8 '13 at 9:34











                                  • A vote for knowing how to copy a Date in less than 3 lines of code.

                                    – RobG
                                    Dec 2 '14 at 12:32
















                                  6














                                  function clone(src, deep) {

                                  var toString = Object.prototype.toString;
                                  if(!src && typeof src != "object"){
                                  //any non-object ( Boolean, String, Number ), null, undefined, NaN
                                  return src;
                                  }

                                  //Honor native/custom clone methods
                                  if(src.clone && toString.call(src.clone) == "[object Function]"){
                                  return src.clone(deep);
                                  }

                                  //DOM Elements
                                  if(src.nodeType && toString.call(src.cloneNode) == "[object Function]"){
                                  return src.cloneNode(deep);
                                  }

                                  //Date
                                  if(toString.call(src) == "[object Date]"){
                                  return new Date(src.getTime());
                                  }

                                  //RegExp
                                  if(toString.call(src) == "[object RegExp]"){
                                  return new RegExp(src);
                                  }

                                  //Function
                                  if(toString.call(src) == "[object Function]"){
                                  //Wrap in another method to make sure == is not true;
                                  //Note: Huge performance issue due to closures, comment this :)
                                  return (function(){
                                  src.apply(this, arguments);
                                  });

                                  }

                                  var ret, index;
                                  //Array
                                  if(toString.call(src) == "[object Array]"){
                                  //.slice(0) would soft clone
                                  ret = src.slice();
                                  if(deep){
                                  index = ret.length;
                                  while(index--){
                                  ret[index] = clone(ret[index], true);
                                  }
                                  }
                                  }
                                  //Object
                                  else {
                                  ret = src.constructor ? new src.constructor() : {};
                                  for (var prop in src) {
                                  ret[prop] = deep
                                  ? clone(src[prop], true)
                                  : src[prop];
                                  }
                                  }

                                  return ret;
                                  };





                                  share|improve this answer


























                                  • Did this solution help you ? Let me know if u see any issues.

                                    – user1547016
                                    Aug 1 '12 at 17:00






                                  • 2





                                    if(!src && typeof src != "object"){. I think that should be || not &&.

                                    – MikeM
                                    Apr 8 '13 at 9:34











                                  • A vote for knowing how to copy a Date in less than 3 lines of code.

                                    – RobG
                                    Dec 2 '14 at 12:32














                                  6












                                  6








                                  6







                                  function clone(src, deep) {

                                  var toString = Object.prototype.toString;
                                  if(!src && typeof src != "object"){
                                  //any non-object ( Boolean, String, Number ), null, undefined, NaN
                                  return src;
                                  }

                                  //Honor native/custom clone methods
                                  if(src.clone && toString.call(src.clone) == "[object Function]"){
                                  return src.clone(deep);
                                  }

                                  //DOM Elements
                                  if(src.nodeType && toString.call(src.cloneNode) == "[object Function]"){
                                  return src.cloneNode(deep);
                                  }

                                  //Date
                                  if(toString.call(src) == "[object Date]"){
                                  return new Date(src.getTime());
                                  }

                                  //RegExp
                                  if(toString.call(src) == "[object RegExp]"){
                                  return new RegExp(src);
                                  }

                                  //Function
                                  if(toString.call(src) == "[object Function]"){
                                  //Wrap in another method to make sure == is not true;
                                  //Note: Huge performance issue due to closures, comment this :)
                                  return (function(){
                                  src.apply(this, arguments);
                                  });

                                  }

                                  var ret, index;
                                  //Array
                                  if(toString.call(src) == "[object Array]"){
                                  //.slice(0) would soft clone
                                  ret = src.slice();
                                  if(deep){
                                  index = ret.length;
                                  while(index--){
                                  ret[index] = clone(ret[index], true);
                                  }
                                  }
                                  }
                                  //Object
                                  else {
                                  ret = src.constructor ? new src.constructor() : {};
                                  for (var prop in src) {
                                  ret[prop] = deep
                                  ? clone(src[prop], true)
                                  : src[prop];
                                  }
                                  }

                                  return ret;
                                  };





                                  share|improve this answer















                                  function clone(src, deep) {

                                  var toString = Object.prototype.toString;
                                  if(!src && typeof src != "object"){
                                  //any non-object ( Boolean, String, Number ), null, undefined, NaN
                                  return src;
                                  }

                                  //Honor native/custom clone methods
                                  if(src.clone && toString.call(src.clone) == "[object Function]"){
                                  return src.clone(deep);
                                  }

                                  //DOM Elements
                                  if(src.nodeType && toString.call(src.cloneNode) == "[object Function]"){
                                  return src.cloneNode(deep);
                                  }

                                  //Date
                                  if(toString.call(src) == "[object Date]"){
                                  return new Date(src.getTime());
                                  }

                                  //RegExp
                                  if(toString.call(src) == "[object RegExp]"){
                                  return new RegExp(src);
                                  }

                                  //Function
                                  if(toString.call(src) == "[object Function]"){
                                  //Wrap in another method to make sure == is not true;
                                  //Note: Huge performance issue due to closures, comment this :)
                                  return (function(){
                                  src.apply(this, arguments);
                                  });

                                  }

                                  var ret, index;
                                  //Array
                                  if(toString.call(src) == "[object Array]"){
                                  //.slice(0) would soft clone
                                  ret = src.slice();
                                  if(deep){
                                  index = ret.length;
                                  while(index--){
                                  ret[index] = clone(ret[index], true);
                                  }
                                  }
                                  }
                                  //Object
                                  else {
                                  ret = src.constructor ? new src.constructor() : {};
                                  for (var prop in src) {
                                  ret[prop] = deep
                                  ? clone(src[prop], true)
                                  : src[prop];
                                  }
                                  }

                                  return ret;
                                  };






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Jul 31 '12 at 20:53


























                                  community wiki





                                  user1547016














                                  • Did this solution help you ? Let me know if u see any issues.

                                    – user1547016
                                    Aug 1 '12 at 17:00






                                  • 2





                                    if(!src && typeof src != "object"){. I think that should be || not &&.

                                    – MikeM
                                    Apr 8 '13 at 9:34











                                  • A vote for knowing how to copy a Date in less than 3 lines of code.

                                    – RobG
                                    Dec 2 '14 at 12:32



















                                  • Did this solution help you ? Let me know if u see any issues.

                                    – user1547016
                                    Aug 1 '12 at 17:00






                                  • 2





                                    if(!src && typeof src != "object"){. I think that should be || not &&.

                                    – MikeM
                                    Apr 8 '13 at 9:34











                                  • A vote for knowing how to copy a Date in less than 3 lines of code.

                                    – RobG
                                    Dec 2 '14 at 12:32

















                                  Did this solution help you ? Let me know if u see any issues.

                                  – user1547016
                                  Aug 1 '12 at 17:00





                                  Did this solution help you ? Let me know if u see any issues.

                                  – user1547016
                                  Aug 1 '12 at 17:00




                                  2




                                  2





                                  if(!src && typeof src != "object"){. I think that should be || not &&.

                                  – MikeM
                                  Apr 8 '13 at 9:34





                                  if(!src && typeof src != "object"){. I think that should be || not &&.

                                  – MikeM
                                  Apr 8 '13 at 9:34













                                  A vote for knowing how to copy a Date in less than 3 lines of code.

                                  – RobG
                                  Dec 2 '14 at 12:32





                                  A vote for knowing how to copy a Date in less than 3 lines of code.

                                  – RobG
                                  Dec 2 '14 at 12:32











                                  6














                                  I've written my own implementation. Not sure if it counts as a better solution:



                                  /*
                                  a function for deep cloning objects that contains other nested objects and circular structures.
                                  objects are stored in a 3D array, according to their length (number of properties) and their depth in the original object.
                                  index (z)
                                  |
                                  |
                                  |
                                  |
                                  |
                                  | depth (x)
                                  |_ _ _ _ _ _ _ _ _ _ _ _
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/...../
                                  /................./
                                  /..... /
                                  / /
                                  /------------------
                                  object length (y) /
                                  */


                                  Following is the implementation:



                                  function deepClone(obj) {
                                  var depth = -1;
                                  var arr = ;
                                  return clone(obj, arr, depth);
                                  }

                                  /**
                                  *
                                  * @param obj source object
                                  * @param arr 3D array to store the references to objects
                                  * @param depth depth of the current object relative to the passed 'obj'
                                  * @returns {*}
                                  */
                                  function clone(obj, arr, depth){
                                  if (typeof obj !== "object") {
                                  return obj;
                                  }

                                  var length = Object.keys(obj).length; // native method to get the number of properties in 'obj'

                                  var result = Object.create(Object.getPrototypeOf(obj)); // inherit the prototype of the original object
                                  if(result instanceof Array){
                                  result.length = length;
                                  }

                                  depth++; // depth is increased because we entered an object here

                                  arr[depth] = ; // this is the x-axis, each index here is the depth
                                  arr[depth][length] = ; // this is the y-axis, each index is the length of the object (aka number of props)
                                  // start the depth at current and go down, cyclic structures won't form on depths more than the current one
                                  for(var x = depth; x >= 0; x--){
                                  // loop only if the array at this depth and length already have elements
                                  if(arr[x][length]){
                                  for(var index = 0; index < arr[x][length].length; index++){
                                  if(obj === arr[x][length][index]){
                                  return obj;
                                  }
                                  }
                                  }
                                  }

                                  arr[depth][length].push(obj); // store the object in the array at the current depth and length
                                  for (var prop in obj) {
                                  if (obj.hasOwnProperty(prop)) result[prop] = clone(obj[prop], arr, depth);
                                  }

                                  return result;
                                  }





                                  share|improve this answer


























                                  • not working for my object, although my case is a little bit complex.

                                    – Sajuuk
                                    Jan 2 at 6:33
















                                  6














                                  I've written my own implementation. Not sure if it counts as a better solution:



                                  /*
                                  a function for deep cloning objects that contains other nested objects and circular structures.
                                  objects are stored in a 3D array, according to their length (number of properties) and their depth in the original object.
                                  index (z)
                                  |
                                  |
                                  |
                                  |
                                  |
                                  | depth (x)
                                  |_ _ _ _ _ _ _ _ _ _ _ _
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/...../
                                  /................./
                                  /..... /
                                  / /
                                  /------------------
                                  object length (y) /
                                  */


                                  Following is the implementation:



                                  function deepClone(obj) {
                                  var depth = -1;
                                  var arr = ;
                                  return clone(obj, arr, depth);
                                  }

                                  /**
                                  *
                                  * @param obj source object
                                  * @param arr 3D array to store the references to objects
                                  * @param depth depth of the current object relative to the passed 'obj'
                                  * @returns {*}
                                  */
                                  function clone(obj, arr, depth){
                                  if (typeof obj !== "object") {
                                  return obj;
                                  }

                                  var length = Object.keys(obj).length; // native method to get the number of properties in 'obj'

                                  var result = Object.create(Object.getPrototypeOf(obj)); // inherit the prototype of the original object
                                  if(result instanceof Array){
                                  result.length = length;
                                  }

                                  depth++; // depth is increased because we entered an object here

                                  arr[depth] = ; // this is the x-axis, each index here is the depth
                                  arr[depth][length] = ; // this is the y-axis, each index is the length of the object (aka number of props)
                                  // start the depth at current and go down, cyclic structures won't form on depths more than the current one
                                  for(var x = depth; x >= 0; x--){
                                  // loop only if the array at this depth and length already have elements
                                  if(arr[x][length]){
                                  for(var index = 0; index < arr[x][length].length; index++){
                                  if(obj === arr[x][length][index]){
                                  return obj;
                                  }
                                  }
                                  }
                                  }

                                  arr[depth][length].push(obj); // store the object in the array at the current depth and length
                                  for (var prop in obj) {
                                  if (obj.hasOwnProperty(prop)) result[prop] = clone(obj[prop], arr, depth);
                                  }

                                  return result;
                                  }





                                  share|improve this answer


























                                  • not working for my object, although my case is a little bit complex.

                                    – Sajuuk
                                    Jan 2 at 6:33














                                  6












                                  6








                                  6







                                  I've written my own implementation. Not sure if it counts as a better solution:



                                  /*
                                  a function for deep cloning objects that contains other nested objects and circular structures.
                                  objects are stored in a 3D array, according to their length (number of properties) and their depth in the original object.
                                  index (z)
                                  |
                                  |
                                  |
                                  |
                                  |
                                  | depth (x)
                                  |_ _ _ _ _ _ _ _ _ _ _ _
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/...../
                                  /................./
                                  /..... /
                                  / /
                                  /------------------
                                  object length (y) /
                                  */


                                  Following is the implementation:



                                  function deepClone(obj) {
                                  var depth = -1;
                                  var arr = ;
                                  return clone(obj, arr, depth);
                                  }

                                  /**
                                  *
                                  * @param obj source object
                                  * @param arr 3D array to store the references to objects
                                  * @param depth depth of the current object relative to the passed 'obj'
                                  * @returns {*}
                                  */
                                  function clone(obj, arr, depth){
                                  if (typeof obj !== "object") {
                                  return obj;
                                  }

                                  var length = Object.keys(obj).length; // native method to get the number of properties in 'obj'

                                  var result = Object.create(Object.getPrototypeOf(obj)); // inherit the prototype of the original object
                                  if(result instanceof Array){
                                  result.length = length;
                                  }

                                  depth++; // depth is increased because we entered an object here

                                  arr[depth] = ; // this is the x-axis, each index here is the depth
                                  arr[depth][length] = ; // this is the y-axis, each index is the length of the object (aka number of props)
                                  // start the depth at current and go down, cyclic structures won't form on depths more than the current one
                                  for(var x = depth; x >= 0; x--){
                                  // loop only if the array at this depth and length already have elements
                                  if(arr[x][length]){
                                  for(var index = 0; index < arr[x][length].length; index++){
                                  if(obj === arr[x][length][index]){
                                  return obj;
                                  }
                                  }
                                  }
                                  }

                                  arr[depth][length].push(obj); // store the object in the array at the current depth and length
                                  for (var prop in obj) {
                                  if (obj.hasOwnProperty(prop)) result[prop] = clone(obj[prop], arr, depth);
                                  }

                                  return result;
                                  }





                                  share|improve this answer















                                  I've written my own implementation. Not sure if it counts as a better solution:



                                  /*
                                  a function for deep cloning objects that contains other nested objects and circular structures.
                                  objects are stored in a 3D array, according to their length (number of properties) and their depth in the original object.
                                  index (z)
                                  |
                                  |
                                  |
                                  |
                                  |
                                  | depth (x)
                                  |_ _ _ _ _ _ _ _ _ _ _ _
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/_/_/_/
                                  /_/_/_/_/_/_/...../
                                  /................./
                                  /..... /
                                  / /
                                  /------------------
                                  object length (y) /
                                  */


                                  Following is the implementation:



                                  function deepClone(obj) {
                                  var depth = -1;
                                  var arr = ;
                                  return clone(obj, arr, depth);
                                  }

                                  /**
                                  *
                                  * @param obj source object
                                  * @param arr 3D array to store the references to objects
                                  * @param depth depth of the current object relative to the passed 'obj'
                                  * @returns {*}
                                  */
                                  function clone(obj, arr, depth){
                                  if (typeof obj !== "object") {
                                  return obj;
                                  }

                                  var length = Object.keys(obj).length; // native method to get the number of properties in 'obj'

                                  var result = Object.create(Object.getPrototypeOf(obj)); // inherit the prototype of the original object
                                  if(result instanceof Array){
                                  result.length = length;
                                  }

                                  depth++; // depth is increased because we entered an object here

                                  arr[depth] = ; // this is the x-axis, each index here is the depth
                                  arr[depth][length] = ; // this is the y-axis, each index is the length of the object (aka number of props)
                                  // start the depth at current and go down, cyclic structures won't form on depths more than the current one
                                  for(var x = depth; x >= 0; x--){
                                  // loop only if the array at this depth and length already have elements
                                  if(arr[x][length]){
                                  for(var index = 0; index < arr[x][length].length; index++){
                                  if(obj === arr[x][length][index]){
                                  return obj;
                                  }
                                  }
                                  }
                                  }

                                  arr[depth][length].push(obj); // store the object in the array at the current depth and length
                                  for (var prop in obj) {
                                  if (obj.hasOwnProperty(prop)) result[prop] = clone(obj[prop], arr, depth);
                                  }

                                  return result;
                                  }






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Jul 29 '16 at 16:32


























                                  community wiki





                                  3 revs, 2 users 70%
                                  yazjisuhail














                                  • not working for my object, although my case is a little bit complex.

                                    – Sajuuk
                                    Jan 2 at 6:33



















                                  • not working for my object, although my case is a little bit complex.

                                    – Sajuuk
                                    Jan 2 at 6:33

















                                  not working for my object, although my case is a little bit complex.

                                  – Sajuuk
                                  Jan 2 at 6:33





                                  not working for my object, although my case is a little bit complex.

                                  – Sajuuk
                                  Jan 2 at 6:33











                                  5














                                  I just wanted to add to all the Object.create solutions in this post, that this does not work in the desired way with nodejs.



                                  In Firefox the result of



                                  var a = {"test":"test"};
                                  var b = Object.create(a);
                                  console.log(b);´


                                  is



                                  {test:"test"}.



                                  In nodejs it is



                                  {}





                                  share|improve this answer


























                                  • No this is wrong. b.test returns test.

                                    – Shripad Krishna
                                    Oct 16 '13 at 20:15











                                  • This is prototypal inheritance, not cloning.

                                    – d13
                                    Jan 16 '14 at 16:15






                                  • 1





                                    @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

                                    – froginvasion
                                    Aug 8 '14 at 15:28











                                  • @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

                                    – d13
                                    Aug 8 '14 at 18:28











                                  • @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

                                    – froginvasion
                                    Aug 9 '14 at 10:13
















                                  5














                                  I just wanted to add to all the Object.create solutions in this post, that this does not work in the desired way with nodejs.



                                  In Firefox the result of



                                  var a = {"test":"test"};
                                  var b = Object.create(a);
                                  console.log(b);´


                                  is



                                  {test:"test"}.



                                  In nodejs it is



                                  {}





                                  share|improve this answer


























                                  • No this is wrong. b.test returns test.

                                    – Shripad Krishna
                                    Oct 16 '13 at 20:15











                                  • This is prototypal inheritance, not cloning.

                                    – d13
                                    Jan 16 '14 at 16:15






                                  • 1





                                    @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

                                    – froginvasion
                                    Aug 8 '14 at 15:28











                                  • @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

                                    – d13
                                    Aug 8 '14 at 18:28











                                  • @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

                                    – froginvasion
                                    Aug 9 '14 at 10:13














                                  5












                                  5








                                  5







                                  I just wanted to add to all the Object.create solutions in this post, that this does not work in the desired way with nodejs.



                                  In Firefox the result of



                                  var a = {"test":"test"};
                                  var b = Object.create(a);
                                  console.log(b);´


                                  is



                                  {test:"test"}.



                                  In nodejs it is



                                  {}





                                  share|improve this answer















                                  I just wanted to add to all the Object.create solutions in this post, that this does not work in the desired way with nodejs.



                                  In Firefox the result of



                                  var a = {"test":"test"};
                                  var b = Object.create(a);
                                  console.log(b);´


                                  is



                                  {test:"test"}.



                                  In nodejs it is



                                  {}






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  answered Jun 3 '12 at 9:29


























                                  community wiki





                                  heinob














                                  • No this is wrong. b.test returns test.

                                    – Shripad Krishna
                                    Oct 16 '13 at 20:15











                                  • This is prototypal inheritance, not cloning.

                                    – d13
                                    Jan 16 '14 at 16:15






                                  • 1





                                    @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

                                    – froginvasion
                                    Aug 8 '14 at 15:28











                                  • @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

                                    – d13
                                    Aug 8 '14 at 18:28











                                  • @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

                                    – froginvasion
                                    Aug 9 '14 at 10:13



















                                  • No this is wrong. b.test returns test.

                                    – Shripad Krishna
                                    Oct 16 '13 at 20:15











                                  • This is prototypal inheritance, not cloning.

                                    – d13
                                    Jan 16 '14 at 16:15






                                  • 1





                                    @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

                                    – froginvasion
                                    Aug 8 '14 at 15:28











                                  • @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

                                    – d13
                                    Aug 8 '14 at 18:28











                                  • @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

                                    – froginvasion
                                    Aug 9 '14 at 10:13

















                                  No this is wrong. b.test returns test.

                                  – Shripad Krishna
                                  Oct 16 '13 at 20:15





                                  No this is wrong. b.test returns test.

                                  – Shripad Krishna
                                  Oct 16 '13 at 20:15













                                  This is prototypal inheritance, not cloning.

                                  – d13
                                  Jan 16 '14 at 16:15





                                  This is prototypal inheritance, not cloning.

                                  – d13
                                  Jan 16 '14 at 16:15




                                  1




                                  1





                                  @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

                                  – froginvasion
                                  Aug 8 '14 at 15:28





                                  @d13 while your argument is valid, note that there is no standardized way in JavaScript to clone an object. This is prototypical inheritance, but it can be used as clones nevertheless if you understand the concepts.

                                  – froginvasion
                                  Aug 8 '14 at 15:28













                                  @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

                                  – d13
                                  Aug 8 '14 at 18:28





                                  @froginvasion. The only problem with using Object.create is that nested objects and arrays are just pointer references to the prototype's nested objects and arrays. jsbin.com/EKivInO/2/edit?js,console. Technically a "cloned" object should have its own unique properties that are not shared references to properties on other objects.

                                  – d13
                                  Aug 8 '14 at 18:28













                                  @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

                                  – froginvasion
                                  Aug 9 '14 at 10:13





                                  @d13 okay, I see your point now. But what I meant is that too many people are alienated with the concept of prototypical inheritance, and to me fail to learn how it works. If I'm not mistaken, your example can be fixed by just calling Object.hasOwnProperty to check whether you own the array or not. Yes this does add additional complexity to deal with prototypical inheritance.

                                  – froginvasion
                                  Aug 9 '14 at 10:13











                                  5














                                  Since mindeavor stated that the object to be cloned is a 'literal-constructed' object, a solution might be to simply generate the object multiple times rather than cloning an instance of the object:



                                  function createMyObject()
                                  {
                                  var myObject =
                                  {
                                  ...
                                  };
                                  return myObject;
                                  }

                                  var myObjectInstance1 = createMyObject();
                                  var myObjectInstance2 = createMyObject();





                                  share|improve this answer






























                                    5














                                    Since mindeavor stated that the object to be cloned is a 'literal-constructed' object, a solution might be to simply generate the object multiple times rather than cloning an instance of the object:



                                    function createMyObject()
                                    {
                                    var myObject =
                                    {
                                    ...
                                    };
                                    return myObject;
                                    }

                                    var myObjectInstance1 = createMyObject();
                                    var myObjectInstance2 = createMyObject();





                                    share|improve this answer




























                                      5












                                      5








                                      5







                                      Since mindeavor stated that the object to be cloned is a 'literal-constructed' object, a solution might be to simply generate the object multiple times rather than cloning an instance of the object:



                                      function createMyObject()
                                      {
                                      var myObject =
                                      {
                                      ...
                                      };
                                      return myObject;
                                      }

                                      var myObjectInstance1 = createMyObject();
                                      var myObjectInstance2 = createMyObject();





                                      share|improve this answer















                                      Since mindeavor stated that the object to be cloned is a 'literal-constructed' object, a solution might be to simply generate the object multiple times rather than cloning an instance of the object:



                                      function createMyObject()
                                      {
                                      var myObject =
                                      {
                                      ...
                                      };
                                      return myObject;
                                      }

                                      var myObjectInstance1 = createMyObject();
                                      var myObjectInstance2 = createMyObject();






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited May 23 '17 at 12:34


























                                      community wiki





                                      2 revs
                                      Bert Regelink























                                          1 2
                                          next




                                          protected by acdcjunior Apr 5 '14 at 12:41



                                          Thank you for your interest in this question.
                                          Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                          Would you like to answer one of these unanswered questions instead?



                                          Popular posts from this blog

                                          List item for chat from Array inside array React Native

                                          Thiostrepton

                                          Caerphilly