2016-06-14 50 views
0

我创建了变量bpJson,并不理解它为什么会改变。我每5秒钟都会对控制台进行日志记录,并且每次迭代都会更改一次。我只希望babyPieData改变,而bpJson每次都保持不变。 setPieOptions中没有bpJson,所以我没有包含该函数的代码。为什么我的变量的副本被意外更改?

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

偏离主题,因为“为什么不是这个代码工作。” – bhspencer

+0

@bhspencer ??那是什么意思?这是关于某些代码的问题,并且代码已发布。 – Pointy

+0

关闭一个问题的原因之一是“寻求调试帮助的问题(”为什么这个代码不工作?“)必须包含所需的行为,特定的问题或错误以及在问题本身中重现问题所需的最短代码。没有明确问题陈述的问题对其他读者无益。请参阅:如何创建最小,完整和可验证示例。' – bhspencer

回答

4

从你的代码中,很明显你正在使用一个对象;它看起来可能是一个数组。

变量不直接包含像数组这样的对象,它们包含引用给它们;实际的对象是其他地方。你可以想象它为在一个数字,它告诉JavaScript引擎在哪里可以找到对象的变量:

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

所以,问题是,这条线没有做什么你认为它的作用:

var bpJson = babyPieData; 

这不会创建数组的副本。它只是创建参考的第二个副本到阵列。这两个变量仍然引用(点)在同一个阵列:

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

如果你想在阵列复制,你需要做的目的。如果数组包含简单的值(因为它似乎),你可以做这样的:

var bpJson = babyPieData.slice(); 

slice不带参数创建一个浅表副本:

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

我不知道一个变量只是对象的引用。您的解释对帮助我理解代码无法正常工作和非常感激非常有帮助。 – Mike

+0

想知道你用什么来创造这个... – Himanshu

+0

@Mike:很高兴帮助!是的,变量直接包含像数字和布尔值之类的基本元素的值(无论如何都是对它们的标准解释),但对于对象(包括数组)来说,它是一个参考值(如数字)。 –

3

由于bpJsonbabyPieData是相同的对象。

+3

请考虑关闭一个脱离主题的问题,因为“为什么不是这个代码工作。”而不是写一个单行的答案。 – bhspencer

+2

@bhspencer这个问题不是题外话。它包含问题的代码,并包含问题的描述。这可能不是有史以来最大的问题,但足以看到问题并提供答案。 – Pointy

相关问题