简体   繁体   中英

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);
    };
}();

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   |
                            +−−−−−−−−−+

因为bpJsonbabyPieData是同一对象。

"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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM