0

Hi I have a JSON Object

var A = {"Name:""Abd'Allah", "Age":43, "Homeland":"Australia"};

Now I copy to B and add/delete/modify some attributes

var B = A;
delete B.Homeland;

Now the issue is when I deleted the value from B, it got deleted from A as well. Why? How JSON variable got copied?

Currently what I am doing is

var B = JSON.parse(JSON.stringify(A));

But this is kind of stupid. What is the right way to do it?

Muhammad Raihan Muhaimin
  • 5,559
  • 7
  • 47
  • 68
  • 1
    `A` doesn't technically have the object as its value, but rather a reference to that object. And, `var B = A;` only copies the reference, so both variables independently refer to the same object. 1) [Is JavaScript a pass-by-reference or pass-by-value language?](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) 2) [Most efficient way to clone an object?](http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object) – Jonathan Lonowski Mar 05 '14 at 23:13
  • 1
    Take a look to the [Most Elegant way to clone a javascript object](http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object) – Joqus Mar 05 '14 at 23:18

2 Answers2

4

Often, the best way to do it is this:

var B = Object.create(A)

After that you can do with B whatever you want, and A won't be changed (but the opposite is not always true).

It's not really copies the object (it sets up a prototype chain instead), but please check if it works for you.

alex
  • 11,935
  • 3
  • 30
  • 42
2

Assign an object or an array in javascript does not make a copy. When you do

var B = A;

you now simply have two variables pointing at the exact same object. If you modify that object (through either variable), there is only one object so both reference to that object will see the change.

If you want to copy an object in javascript, you can make a shallow copy by simply just copying all the properties from one object to another:

function shallowCopy(obj) {
    var newObj = {};
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            newObj[prop] = obj[prop];
        }
    }
    return newObj;
}

Note, this is a shallow copy. If properties themselves contain other objects, then this won't make new copies of those (it will just copy the reference to them).


With a little more work, you can also do a deep copy where it will make copies of objects contained within the object. The only gotcha for this function is you have to make sure that there are no circular references where A contains a property which contains an object or array which also contains A because this will infinite loop if there is a circular reference.

 function deepCopy(obj) {
    if (typeof obj !== "object" || obj === null) {
        return obj;
    }
    var newObj = obj instanceof Array ? [] : {};
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            newObj[prop] = deepCopy(obj[prop]);
        }
    }
    return newObj;
 }

This function doesn't preserve object types that aren't plain objects (of course, your JSON solution doesn't either). To do that requires even more work involving the constructor.

jfriend00
  • 683,504
  • 96
  • 985
  • 979