为什么变量的副本意外更改? [英] Why is a copy of my variable being changed unexpectedly?

查看:30
本文介绍了为什么变量的副本意外更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了变量bpJson,但不了解为什么它会更改.我在控制台每5秒记录一次,并且每次迭代都会更改.我只希望babyPieData发生变化,而bpJson每次都保持不变.setPieOptions中没有bpJson,因此我没有包含该函数的代码.

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.

变量不直接包含数组之类的对象,它们包含对它们的引用;实际对象在其他地方.您可以将其描述为其中包含数字的变量,该变量告诉JavaScript引擎在哪里找到对象:

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;

这不会创建数组的副本.它只是为该数组创建 reference 的第二个副本.这两个变量仍然引用(指向)同一数组:

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 创建浅表副本:

slice with no arguments creates a shallow copy:


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

这篇关于为什么变量的副本意外更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆