181
votes

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?

2
There is no JSON there. Please don't confuse JavaScript objects with JSON. - Quentin
@Quentin, thanks I'll read up on the difference between javacript objects and json (ref: stackoverflow.com/questions/6489783/…) - Prusprus
Don't think it's a duplicate, the answer was not found on the other thread. - Prusprus
@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? - Prusprus
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" - Quentin

2 Answers

259
votes

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

116
votes

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.