我创建了变量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 :(得分: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 | +---------+
答案 1 :(得分:3)
因为bpJson
和babyPieData
是同一个对象。
答案 2 :(得分:-1)
"How to clone a js object elegantly"
正如@Scott&#34所说;因为bpJson和babyPieData是同一个对象。&#34; 按照链接创建任何js对象的独立副本,而不是特定的数组。