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

相關問題