【问题标题】:Pushing into array gives unexpected result推入数组会产生意想不到的结果
【发布时间】:2016-04-15 20:31:27
【问题描述】:
下面的代码 sn-p 返回意外的(至少对我而言)结果。
var input = [['one','two'],['three','four']];
var doc = {};
var output1 = [], output2 = [];
input.forEach(function(x){
doc.firstValue = x[0];
doc.secondValue = x[1];
output1.push({firstValue:x[0],secondValue:x[1]});
output2.push(doc);
})
$('#output1').html(JSON.stringify(output1));
$('#output2').html(JSON.stringify(output2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
output1 is:
<div id='output1'></div>
output2 is:
<div id='output2'></div>
问题是:
1) 为什么 output1 看起来与 output2 不相似(虽然它们的创建非常相似)?
2) 有没有办法像 array.push(obj) 一样推入数组(填充 output2 的方式)并获得像 output1 这样的结果(初始数组中的所有值都在那里)?
【问题讨论】:
标签:
javascript
arrays
foreach
javascript-objects
【解决方案1】:
1) 为什么 output1 看起来与 output2 不相似(而它们的创建非常相似)?
这与 JavaScript 中的 closure 有关。
您的output2 数组包含两个对doc 对象的引用。这些引用都指向doc 的相同 实例。
所以当你的任务完成并打印output2的内容时,你意识到它只是打印doc的值,即
{
"firstValue":"three",
"secondValue":"four"
}
2) 有没有办法像 array.push(obj) 一样推入数组(填充 output2 的方式)并获得像 output1 一样的结果(初始数组中的所有值都会在那里)?
执行此操作的最简单方法是每次要使用 doc 的新实例以避免关闭:
var output1 = [], output2 = [];
input.forEach(function(x){
// Declare and define `doc` here to get unique references.
var doc = {};
doc.firstValue = x[0];
doc.secondValue = x[1];
output1.push({firstValue:x[0],secondValue:x[1]});
output2.push(doc);
});
【解决方案2】:
试试这个:
var input = [['one','two'],['three','four']];
var doc = {};
var output1 = [], output2 = [];
input.forEach(function(x){
doc = {}; //this is the added line
doc.firstValue = x[0];
doc.secondValue = x[1];
output1.push({firstValue:x[0],secondValue:x[1]});
output2.push(doc);
})
$('#output1').html(JSON.stringify(output1));
$('#output2').html(JSON.stringify(output2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
output1 is:
<div id='output1'></div>
output2 is:
<div id='output2'></div>
您应该在每次迭代中创建一个新的doc object...您引用的是同一个对象,因此其中包含最新的值...