推入数组会产生意想不到的结果

Pushing into array gives unexpected result

下面的代码片段 returns 结果出乎意料(至少对我而言)。

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 这样的结果(初始数组中的所有值都在那里)?

试试这个:

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...您引用的是同一个对象,因此它会包含最新的值...

1) why output1 doesn't look similar to output2 (while their creation is quite similar)?

这与 JavaScript 中的 closure 有关。

您的 output2 数组包含对 doc 对象的两个 引用 。这些引用都指向 doc 相同 实例。

所以当你的任务全部完成并且你正在打印 output2 的内容时,你意识到它只是打印 doc 的值,即

{
   "firstValue":"three",
   "secondValue":"four"
}

2) is there a way to push into array like array.push(obj) (the way output2 is filled) and getting the result like output1 (all the values from initial array would be there)?

最简单的方法是在每次要使用它时创建一个新实例 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); 
});