0

it might be too late at night already and I might become crazy but how can this be.

I have the following scenario:

var x = {a: [], b: []};
var y = {a: [], b: []};

Model.someFunction(obj1, function(res){
    x.a = res;
    y.a = res;
    Model.someFunction(obj2, function(res){
        x.b = res;
        y.b = res;

        macheWasAnderes();
        // Content of both objects:
        // x = {a: [punkt1: 20, punkt2: 30}, b: {punkt1: 50, punkt2: 60}]};
        // y = {a: [punkt1: 20, punkt2: 30}, b: {punkt1: 50, punkt2: 60}]};
    });
});

function macheWasAnderes(){
  for(let prop in x){
    for(let i = 0; i < x[prop].length; i++){
        for(let propa in x[prop][i]){
            x[prop][i][propa] = x[prop][i][propa] / 100;
        }
    }
  }

  console.log("x", x);
  console.log("y", y);
  // x = {a: [punkt1: 0.02, punkt2: 0.03}, b: {punkt1: 0.05, punkt2: 0.06}]};
  // y = {a: [punkt1: 0.02, punkt2: 0.03}, b: {punkt1: 0.05, punkt2: 0.06}]};
}

As you can see I am receiving some Data from my callbacks of my Model-functions. When these are done I am calling the machWasAnderes() function in order to calculate with my x object. For this example I am just changing dividing it's value by a hundred and saving it that way.

Strangely enough when I print out both objects, the object y also got the calculated values...

How can this be ?

note This is not my exact code. My code is much longer so I have created an simpler copy of my code which contains the issue.

noa-dev
  • 3,561
  • 9
  • 34
  • 72
  • 2
    I don't follow your question exactly, but this sounds like a problem where an assignment of an object in Javascript is like sharing a pointer, NOT making a copy. So, after assigning one object to a variable, you now have two variables pointing at the exact same object. Change the object through either and they both see the change. If `res` is an object, then both `x.a` and `y.a` point at the same object. – jfriend00 Feb 26 '16 at 22:57
  • 3
    Both `x.a` and `y.a` reference the same object returned in `res`, the same goes for the `*.b` property, so they are in fact the exact same thing – adeneo Feb 26 '16 at 22:58
  • 3
    Basically, your code can be reduced to `var x, y; x = y = {}; x.a = 123; y.a === 123` – Oriol Feb 26 '16 at 22:59
  • Objects are implemented as references, just like in Java and most other languages that have mutable objects. – Felix Kling Feb 26 '16 at 23:03
  • Thanks for the quick replies! So how can I work around that If I want both object to initially have the value of res? And btw, res is an array containing other objects. – noa-dev Feb 26 '16 at 23:04
  • 1
    `x.a = JSON.parse( JSON.stringify(res) );`, if it's arrays, `x.a = res.slice(0)` probably does it to – adeneo Feb 26 '16 at 23:08
  • I'd suggest that rather than assign the whole `res` object, you just make a new object with a couple fields in it that you actually need and assign that to `x.a` and `x.b`. If those fields themselves are not objects, then the problem will be solved. – jfriend00 Feb 26 '16 at 23:15
  • @noa-dev take a look at the link that I have provided with the explanation. It will help you. – pritesh Feb 26 '16 at 23:20
  • @adeneo I used your workaround. Fixed my issue. Not a pretty solution but it works :D – noa-dev Feb 26 '16 at 23:35

1 Answers1

-2

Lets goto some basics. There are two types of copies : shallow copy and deep copy.

  1. Shallow copy is when you copy only reference into other reference and not the data. So basically both references pointing to the same object. That means changing one object will affect on other reference as well.
  2. Deep copy is when you create a duplicate copy of the data and then assign it to the reference.

Coming to your case: When you say

x.a = res;
y.a = res;

Both are referring the same object as you are doing shallow copy. So when you change x.a, it in turn affects y.a as well. Same goes for x.b and y.b

Read this.. https://nikhilmachcha.wordpress.com/2015/08/24/deep-copy-vs-shallow-copy-php-way/

Hope this helps you!!

pritesh
  • 533
  • 4
  • 15
  • If you replace *"shallow copy"* and *"deep copy"* with *"pass by value"* and *"pass by value of a reference"*, you're at least a little closer to being correct. – adeneo Feb 26 '16 at 23:11
  • @adeneo No. That's when you talk about defining and calling the functions. Take a look at this. http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy – pritesh Feb 26 '16 at 23:15
  • @adeneo https://nikhilmachcha.wordpress.com/2015/08/24/deep-copy-vs-shallow-copy-php-way/ – pritesh Feb 26 '16 at 23:21
  • http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference#answer-13104500 – adeneo Feb 26 '16 at 23:28
  • Call it whatever you want, but generally it's called *"pass by value"* and *"pass by reference"*, even though javascript always passes by value, the issue here is that a value of a reference is passed, not the value itself. – adeneo Feb 26 '16 at 23:44
  • `var arrayClone = array.slice(0);` is a shallow copy of an array. `var arrayClone = array;` is **not** a copy. – Felix Kling Feb 27 '16 at 23:33