user5096599
user5096599

Reputation:

Why is a copy of my variable being changed unexpectedly?

I created variable bpJson, and am not understanding why it is changing. I am console logging it every 5 seconds, and it changes each iteration. I only expected babyPieData to change while bpJson stays the same each time. There is no bpJson in setPieOptions so I did not include the code for that function.

var createVariance = function(bpJson, babyPieData){
    var n = bpJson.length;
    for ( var i = 0; i < n; i++){
        var amount = Math.floor(Math.random() * 4);
        var operator = Math.floor(Math.random() *2) + 1;
        if (operator === 1){
            babyPieData[i] = (bpJson[i] + amount);
            if (babyPieData[i] > 100){
                babyPieData[i] = 100;
            }
        }else{
            babyPieData[i] = (bpJson[i] - amount);
            if (babyPieData[i] < 0){
                babyPieData[i] = 1;
            }
        }
        setPieOptions(babyPieData);
    }
};

var getBabyPieData = function(){
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'php/baby-pie.php');
    xhr.send();
    xhr.onload = function(){
        var babyPieData = JSON.parse(xhr.response);
        console.log('original babyPieData = ' + babyPieData);
        var bpJson = babyPieData;
        setPieOptions(babyPieData);
        var babyPieDataTimer = window.setInterval(function(){
            createVariance(bpJson, babyPieData);
            console.log(bpJson);
        }, 5000);
    };
}();

Upvotes: 0

Views: 230

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1074949

From your code, it's clear that you're using an object; it looks like it's probably an array.

Variables don't directly contain objects like arrays, they contain references to them; the actual object is elsewhere. You could picture it as the variable having a number in it which tells the JavaScript engine where to find the object:

+−−−−−−−−−−−−−+             
| babyPieData |             
+−−−−−−−−−−−−−+             +−−−−−−−−−+
| Ref:123456  |−−−−−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+             +−−−−−−−−−+
                            | 0: 42   |
                            | 1: 67   |
                            +−−−−−−−−−+

So the issue is that this line doesn't do what you think it does:

var bpJson = babyPieData;

That doesn't create a copy of the array. It just creates a second copy of the reference to the array. Both variables still refer to (point to) the same array:

+−−−−−−−−−−−−−+       
| babyPieData |       
+−−−−−−−−−−−−−+       
| Ref:123456  |−−−−−−+
+−−−−−−−−−−−−−+      |
                     |
                     |      +−−−−−−−−−+
                     +−−−−−>| (Array) |
+−−−−−−−−−−−−−+      |      +−−−−−−−−−+
| bpjSon      |      |      | 0: 42   |
+−−−−−−−−−−−−−+      |      | 1: 67   |
| Ref:123456  |−−−−−−+      +−−−−−−−−−+
+−−−−−−−−−−−−−+             

If you want to copy the array, you'll need to do that on purpose. If the array contains simple values (as it appears to), you can do that like this:

var bpJson = babyPieData.slice();

slice with no arguments creates a shallow copy:

+−−−−−−−−−−−−−+             
| babyPieData |             
+−−−−−−−−−−−−−+             +−−−−−−−−−+
| Ref:123456  |−−−−−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+             +−−−−−−−−−+
                            | 0: 42   |
                            | 1: 67   |
                            +−−−−−−−−−+
+−−−−−−−−−−−−−+             
| bpJson      |             
+−−−−−−−−−−−−−+             +−−−−−−−−−+
| Ref:554654  |−−−−−−−−−−−−>| (Array) |
+−−−−−−−−−−−−−+             +−−−−−−−−−+
                            | 0: 42   |
                            | 1: 67   |
                            +−−−−−−−−−+

Upvotes: 4

Himanshu
Himanshu

Reputation: 490

"How to clone a js object elegantly"

as already stated by @Scott "Because bpJson and babyPieData are the same object." Follow the link to create an independent copy of any js object, not specifically an array.

Upvotes: -1

Scott Hunter
Scott Hunter

Reputation: 49883

Because bpJson and babyPieData are the same object.

Upvotes: 2

Related Questions