190

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?

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
Prusprus
  • 7,987
  • 9
  • 42
  • 57
  • 33
    There is no JSON there. Please don't confuse JavaScript objects with JSON. – Quentin Aug 21 '13 at 13:43
  • @Quentin, thanks I'll read up on the difference between javacript objects and json (ref: http://stackoverflow.com/questions/6489783/whats-the-difference-between-javascript-object-and-json-object) – Prusprus Aug 21 '13 at 13:49
  • Don't think it's a duplicate, the answer was not found on the other thread. – Prusprus Aug 21 '13 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? – Prusprus Aug 21 '13 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" – Quentin Aug 21 '13 at 14:02
  • This is not a duplicate, Prusprus asked for an answer with javascript not js jquery library... is there no simple way with ES6-ES7 to completely clone js object in a new space in memory? – DrSocket Apr 02 '18 at 04:19
  • Take a look at ES6 Object.assign() – Aditya Prasoon Jun 01 '20 at 18:45
  • I also find lodash's _.clone and _.deepClone simple enough to use. – Aditya Prasoon Jun 01 '20 at 18:46
  • @Bizarre couldnt post new answer, but given `var first = {key: "value"}`, then to clone it in ES6: `var myObj = {...first}`, and in ES5: `var myES5Obj = eval(first.toSource())` – B''H Bi'ezras -- Boruch Hashem Jun 03 '20 at 01:17
  • @AdityaPrasoon is that different than `var nnewObj = {...old}`? – B''H Bi'ezras -- Boruch Hashem Jun 03 '20 at 01:18
  • @bluejayke Almost same, but not really. Check this - https://2ality.com/2016/10/rest-spread-properties.html#spreading-objects-versus-object.assign() – Aditya Prasoon Jun 03 '20 at 08:50
  • Does anyone know why this is a pain, it seems to me that being able to make a copy of something is super useful, why isn't it as simple as '=/=' or something? – Colin Smith Jul 29 '20 at 13:50

2 Answers2

267

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

Andy
  • 61,948
  • 13
  • 68
  • 95
123

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.

Benry
  • 5,298
  • 1
  • 24
  • 25
Moeri
  • 9,104
  • 5
  • 43
  • 56