How to Deep clone in javascript

lodash deep clone
javascript deep clone object
javascript deep copy array
underscore deep clone
javascript clone function
react deep copy
deep clone java
es6 deep copy

How do you deep clone a Javascript object?

I know there are various functions based on frameworks like JSON.parse(JSON.stringify(o)) and $.extend(true, {}, o) but I don't want to use a framework like that.

What is the most elegant or efficient way to create a deep clone.

We do care about edge cases like cloning array's. Not breaking prototype chains, dealing with self reference.

We don't care about supporting copying of DOM objects and like because .cloneNode exists for that reason.

As I mainly want to use deep clones in node.js using ES5 features of the V8 engine is acceptable.

[Edit]

Before anyone suggests let me mention there is a distinct difference between creating a copy by prototypically inheriting from the object and cloning it. The former makes a mess of the prototype chain.

[Further Edit]

After reading your answer I came to the annoying discovery that cloning entire objects is a very dangerous and difficult game. Take for example the following closure based object

var o = (function() {
     var magic = 42;

     var magicContainer = function() {
          this.get = function() { return magic; };
          this.set = function(i) { magic = i; };
     }

      return new magicContainer;
}());

var n = clone(o); // how to implement clone to support closures

Is there any way to write a clone function that clones the object, has the same state at time of cloning but cannot alter the state of o without writing a JS parser in JS.

There should be no real world need for such a function anymore. This is mere academic interest.

It really depends what you would like to clone. Is this a truly JSON object or just any object in JavaScript? If you would like to do any clone, it might get you into some trouble. Which trouble? I will explain it below, but first, a code example which clones object literals, any primitives, arrays and DOM nodes.

function clone(item) {
    if (!item) { return item; } // null, undefined values check

    var types = [ Number, String, Boolean ], 
        result;

    // normalizing primitives if someone did new String('aaa'), or new Number('444');
    types.forEach(function(type) {
        if (item instanceof type) {
            result = type( item );
        }
    });

    if (typeof result == "undefined") {
        if (Object.prototype.toString.call( item ) === "[object Array]") {
            result = [];
            item.forEach(function(child, index, array) { 
                result[index] = clone( child );
            });
        } else if (typeof item == "object") {
            // testing that this is DOM
            if (item.nodeType && typeof item.cloneNode == "function") {
                result = item.cloneNode( true );    
            } else if (!item.prototype) { // check that this is a literal
                if (item instanceof Date) {
                    result = new Date(item);
                } else {
                    // it is an object literal
                    result = {};
                    for (var i in item) {
                        result[i] = clone( item[i] );
                    }
                }
            } else {
                // depending what you would like here,
                // just keep the reference, or create new object
                if (false && item.constructor) {
                    // would not advice to do that, reason? Read below
                    result = new item.constructor();
                } else {
                    result = item;
                }
            }
        } else {
            result = item;
        }
    }

    return result;
}

var copy = clone({
    one : {
        'one-one' : new String("hello"),
        'one-two' : [
            "one", "two", true, "four"
        ]
    },
    two : document.createElement("div"),
    three : [
        {
            name : "three-one",
            number : new Number("100"),
            obj : new function() {
                this.name = "Object test";
            }   
        }
    ]
})

And now, let's talk about problems you might get when start cloning REAL objects. I'm talking now, about objects which you create by doing something like

var User = function(){}
var newuser = new User();

Of course you can clone them, it's not a problem, every object expose constructor property, and you can use it to clone objects, but it will not always work. You also can do simple for in on this objects, but it goes to the same direction - trouble. I have also included clone functionality inside the code, but it's excluded by if( false ) statement.

So, why cloning can be a pain? Well, first of all, every object/instance might have some state. You never can be sure that your objects doesn't have for example an private variables, and if this is the case, by cloning object, you just break the state.

Imagine there is no state, that's fine. Then we still have another problem. Cloning via "constructor" method will give us another obstacle. It's an arguments dependency. You never can be sure, that someone who created this object, did not did, some kind of

new User({
   bike : someBikeInstance
});

If this is the case, you are out of luck, someBikeInstance was probably created in some context and that context is unkown for clone method.

So what to do? You still can do for in solution, and treat such objects like normal object literals, but maybe it's an idea not to clone such objects at all, and just pass the reference of this object?

Another solution is - you could set a convention that all objects which must be cloned should implement this part by themselves and provide appropriate API method ( like cloneObject ). Something what cloneNode is doing for DOM.

You decide.

How to deep clone a JavaScript object, A quick breakdown on how to clone an object in JavaScript the right way through deep cloning using Lodash. For a deep copy, the easiest option is to use reliable external libraries like Lodash. Using Lodash Clone And Clonedeep. Lodash comes with two different functions that allow you to do shallow copies and deep copies. These are clone and clonedeep. The great thing about Lodash is that you can import each function individually, without requiring

Very simple way, maybe too simple:

var cloned = JSON.parse(JSON.stringify(objectToClone));

Deep Cloning Objects In JavaScript (And How It Works), The usual methods of copying an object or array only make a shallow copy, so deeply-nested references are a problem. You need a deep copy if a JavaScript  How to Deep Clone an Array in JavaScript There are 2 types of array cloning: shallow & deep. Shallow copies only cover the 1st level of the array and the rest…

The JSON.parse(JSON.stringify()) combination to deep copy Javascript objects is an ineffective hack, as it was meant for JSON data. It does not support values of undefined or function () {}, and will simply ignore them (or null them) when "stringifying" (marshalling) the Javascript object into JSON.

A better solution is to use a deep copy function. The function below deep copies objects, and does not require a 3rd party library (jQuery, LoDash, etc).

function copy(aObject) {
  if (!aObject) {
    return aObject;
  }

  let v;
  let bObject = Array.isArray(aObject) ? [] : {};
  for (const k in aObject) {
    v = aObject[k];
    bObject[k] = (typeof v === "object") ? copy(v) : v;
  }

  return bObject;
}

How to Deep Copy Objects and Arrays in JavaScript, Lodash DeepClone vs JSON. Here's a comment from the community. Yes, it was for my previous post, How to Deep Clone an Array  JavaScript Deep and Shallow Clone of Object. In this tutorial, we will learn about how to deep and shallow clone an object in JavaScript. Cloning. The cloning of an object creates a new object containing all the fields and values of the original object. The value of a field can be of two types, a primitive type, and an object type.

Here is an ES6 function that will also work for objects with cyclic references:

function deepClone(obj, hash = new WeakMap()) {
    if (Object(obj) !== obj) return obj; // primitives
    if (hash.has(obj)) return hash.get(obj); // cyclic reference
    const result = obj instanceof Set ? new Set(obj) // See note about this!
                 : obj instanceof Map ? new Map(Array.from(obj, ([key, val]) => 
                                        [key, deepClone(val, hash)])) 
                 : obj instanceof Date ? new Date(obj)
                 : obj instanceof RegExp ? new RegExp(obj.source, obj.flags)
                 // ... add here any specific treatment for other classes ...
                 // and finally a catch-all:
                 : obj.constructor ? new obj.constructor() 
                 : Object.create(null);
    hash.set(obj, result);
    return Object.assign(result, ...Object.keys(obj).map(
        key => ({ [key]: deepClone(obj[key], hash) }) ));
}

// Sample data
var p = {
  data: 1,
  children: [{
    data: 2,
    parent: null
  }]
};
p.children[0].parent = p;

var q = deepClone(p);

console.log(q.children[0].parent.data); // 1

3 Ways to Clone Objects in JavaScript, What is the most efficient way to deep clone an object in JavaScript? Copying objects in JavaScript can be tricky. Some ways perform a shallow copy, which is the default behavior in most of the cases. Deep copy vs Shallow copy. Easiest option: use Lodash. Object.assign() Using the Object Spread operator. Wrong solutions Using Object.create() JSON serialization.

The Underscore.js contrib library library has a function called snapshot that deep clones an object

snippet from the source:

snapshot: function(obj) {
  if(obj == null || typeof(obj) != 'object') {
    return obj;
  }

  var temp = new obj.constructor();

  for(var key in obj) {
    if (obj.hasOwnProperty(key)) {
      temp[key] = _.snapshot(obj[key]);
    }
  }

  return temp;
}

once the library is linked to your project, invoke the function simply using

_.snapshot(object);

What is the best and most efficient way to deep clone an object in , , with the spread syntax being the shorter of the two. There are 2 types of array cloning: shallow & deep. Shallow copies only cover the 1st level of the array and the rest are referenced. If you want a true copy of nested arrays, you’ll need a deep clone. For deep clones, go with the JSON way OR better yet use Lodash 👍

Deep copying an object in JavaScript, So How to copy JavaScript object to new variable NOT by reference? Your only option is to somehow clone the object. For simple JSON objects, the simplest way​  He needed to make a copy of the contents of an object which had some data being used to build a table in a user interface. He wanted to modify the copy in order to add code to create custom display markup based on the raw data, but was also going to need to refer back to the original data for various operations.

How to differentiate between deep and shallow copies in JavaScript, By default, when copying by = , javascript keeps the reference to the same object (called a shallow copy). var a = [1,2,3]; var b = a; a[0] = 5;  Let’s start with the first type, the “deep” copy. Deep copy is what you probably think about when you think about copying something. It a 1:1 copy of that something, like a clone. When you create a deep copy, you create a perfect copy of the original. You take all properties from the original and copy them into the copy.

Understanding Deep and Shallow Copy in Javascript, However, those two methods cannot be used to make deep copies of objects. The problem. The spread syntax and the Object.assign() method  A shallow copy will duplicate the top-level properties, but the nested object is shared between the original (source) and the copy (target). Using Object.assign () method. 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.

Comments
  • Before it gets marked duplicate, I looked at stackoverflow.com/questions/122102/… and did not find any answer that dealt with all edge cases.
  • The requirement in the "further edit" section is impossible to achieve without "help" from the object itself, since such private variables are truly private, and by consequence not accessible by a generic clone function. The object in question should expose its own tailor-made clone method.
  • I've been reading about this a bunch tonight, and among the resources I found was this ugly-looking blog post that includes a couple of hacks for accessing the structured clone algorithm in the browser: dassur.ma/things/deep-copy
  • I came apon the hurdle of dealing with objects that use closures to hide state myself. How can one clone an object and its entire state but still ensure the clone cant alter the originals state by itself. A couinter point to result = new item.constructor(); being bad is that given the constructor function & the item object you should be able to RE any paramaters passed into the constructor.
  • @Raynos : if objects use closures to hide state, then you can't clone them. Hence the term 'closure'. As nemisj says at the end, the best way is to implement an API method for cloning (or serialization/deserialization) if that's an option.
  • @MichielKalkman I had a feeling that was the case. Although someone might have had a really clever solution to this.
  • What is the effect of false && item.constructor? Isn't that if useless?
  • @GabrielPetrovay That if is 'useless' from the functional perspective, because it'll never ever run, but it has the academic purpose of showing an hypothetical implementation one might try to use, which author does not advice because of the reason explained later. So, yes, it will trigger else clause everythime the condition is evaluated, and yet there's a reason for the code to be there.
  • Great unless an object value is a function, at which point you'll have to use something like the accepted answer. Or use a helper function like cloneDeep in Lodash.
  • If an object value is a function, the object is no JSON.
  • What use case may justify to clone a function rather than just using it?
  • If i remember correctly this also converts dates into strings.