193

I wrote a quick jsfiddle here, where I pass a small JSON object to a new variable and modify the data from the original variable (not the new variable), but the new variable's data gets updated as well. This must mean that the JSON object was passed by reference, right?

Here is my quick code:

var json_original = {one:'one', two:'two'}

var json_new = json_original;

console.log(json_original); //one, two
console.log(json_new); //one, two

json_original.one = 'two';
json_original.two = 'one';

console.log(json_original); //two, one
console.log(json_new); //two, one

Is there a way to make a deep copy of a JSON object so that modifying the original variable won't modify the new variable?

12
  • 33
    There is no JSON there. Please don't confuse JavaScript objects with JSON. Commented Aug 21, 2013 at 13:43
  • @Quentin, thanks I'll read up on the difference between javacript objects and json (ref: stackoverflow.com/questions/6489783/…) Commented Aug 21, 2013 at 13:49
  • 1
    Don't think it's a duplicate, the answer was not found on the other thread. Commented Aug 21, 2013 at 13:50
  • @Quentin, so it seems that if we were to talk purely within the scope of javascript, JSON and a Javascript Object are equivalent? JSON is different in that it's adaptable to the language used to interpret it? Commented Aug 21, 2013 at 13:59
  • 1
    In the scope of JavaScript, JSON is either "A data format" or "An object containing methods to convert JavaScript objects to and from string representations of that data format" Commented Aug 21, 2013 at 14:02

2 Answers 2

270

Important edit: this answer was made in 2014 and there are now better ways of deep-cloning an object.


I've found that the following works if you're not using jQuery and only interested in cloning simple objects (see comments).

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

Documentation

Sign up to request clarification or add additional context in comments.

14 Comments

Does not work for functions, only properties (variables) within an object.
JSON.stringify({key: undefined}) //=> "{}"
With this, dates will be stringified and will remain strings even after parsed.
Note that this will not work for objects with circular references.
This is why my answer says simple objects, but I guess that could have been clearer.
|
127

Your only option is to somehow clone the object.

See this stackoverflow question on how you can achieve this.

For simple JSON objects, the simplest way would be:

var newObject = JSON.parse(JSON.stringify(oldObject));

if you use jQuery, you can use:

// Shallow copy
var newObject = jQuery.extend({}, oldObject);

// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);

UPDATE 2017: I should mention, since this is a popular answer, that there are now better ways to achieve this using newer versions of javascript:

In ES6 or TypeScript (2.1+):

var shallowCopy = { ...oldObject };

var shallowCopyWithExtraProp = { ...oldObject, extraProp: "abc" };

Note that if extraProp is also a property on oldObject, its value will not be used because the extraProp : "abc" is specified later in the expression, which essentially overrides it. Of course, oldObject will not be modified.

2 Comments

I prefer this answer due to the "In ES6 or TypeScript (2.1+):" section. The example of JQuery deep/shallow copy is nice as well.
I think this should be the answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.