Join the Stack Overflow Community
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

This question already has an answer here:

I am trying to deep copy array of nested objects in javascript. My array look like this

var arr = [{name:"adam",age:"21"},
    {name:"freddie",age:"35",children:[{name:"mercury",age:"25"}]},
    {name:"jim",age:"35",children:[{name:"morrison",age:"25",children:[{name:"some", age:"40"}]}]}
    ];

I want to make a deep copy of every object inside the array that is i want to create a exact copy of arr into new array which should not have object reference. Depth of array is also unknown that is children array can be upto any level. I have gone through this link Copying of an array of objects to another Array without object reference in javascript(Deep copy) but that did not help me. I googled and found some solutions in jQuery but that did not help me as i dont have knowledge of jQuery.

I also tried implementing it with recursion but that's not working too http://ideone.com/kJi5X3

I want to do it in javascript only without using jQuery or anything. I am new to JavaScript so i may have missed if there is any library or simple method to do this. Please help me to solve this problem. Thanks in advance.

share|improve this question

marked as duplicate by James Thorpe, Peter Olson javascript Mar 5 '15 at 15:21

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
You linked to a question that this could have been closed as a duplicate of and said it didn't help - can you clarify why it didn't help, so we understand why this isn't a duplicate of that one? – James Thorpe Mar 5 '15 at 11:03
    
Also note that jQuery is just a javascript library, if there was a jQuery solution, are you ruling out that library while another one would be acceptable? – James Thorpe Mar 5 '15 at 11:04
    
@James Thorpe - No i am wondering if there is any way to do it with recursion or any other logic i dont have knowledge of jQuery and i want to do this ASAP. – user2912611 Mar 5 '15 at 11:07
    
@James That link did not help me because it was not working for nested objects. – user2912611 Mar 5 '15 at 11:09
    
Regarding that potential duplicate - please read beyond the top voted accepted answer - indeed note that that answer itself points you to one of the others. – James Thorpe Mar 5 '15 at 11:13
up vote 4 down vote accepted

You have two main options:

  1. Use JSON.stringify and JSON.parse:

    var copy = JSON.parse(JSON.stringify(original));
    

    But that won't handle Date, RegExp, etc. correctly unless you write a replacer and a reviver.

  2. Use a recursive function, something like this:

var toString = Object.prototype.toString;
function deepCopy(obj) {
    var rv;

    switch (typeof obj) {
        case "object":
            if (obj === null) {
                // null => null
                rv = null;
            } else {
                switch (toString.call(obj)) {
                    case "[object Array]":
                        // It's an array, create a new array with
                        // deep copies of the entries
                        rv = obj.map(deepCopy);
                        break;
                    case "[object Date]":
                        // Clone the date
                        rv = new Date(obj);
                        break;
                    case "[object RegExp]":
                        // Clone the RegExp
                        rv = new RegExp(obj);
                        break;
                    // ...probably a few others
                    default:
                        // Some other kind of object, deep-copy its
                        // properties into a new object
                        rv = Object.keys(obj).reduce(function(prev, key) {
                            prev[key] = deepCopy(obj[key]);
                            return prev;
                        }, {});
                        break;
                }
            }
            break;
        default:
            // It's a primitive, copy via assignment
            rv = obj;
            break;
    }
    return rv;
}
var a = [1, {foo: "bar"}, ['a', 'b'], new Date()];
snippet.log(JSON.stringify(a));
var b = deepCopy(a);
snippet.log(JSON.stringify(b));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Note that the above uses ES5 features present on all modern browsers but not some older ones, like IE8. All of the features used above can be polyfilled, however, for older browsers.

That doesn't try to get into handling custom constructor functions or preserving prototypes on objects in the array; doing so makes things dramatically more complicated and impossible to make perfect without a convention for how to call those constructors for a copy operation. You can get close by assigning the same prototype, but that wouldn't account for logic within the constructor function and in particular for functions set up as closures within it.

share|improve this answer
    
Crowder that worked flawlessly, Thank you very much :) – user2912611 Mar 8 '15 at 11:06

Not the answer you're looking for? Browse other questions tagged or ask your own question.