推入阵列会产生意想不到的结果

时间:2016-04-15 20:31:28

标签: javascript arrays foreach javascript-objects

下面的代码段会返回意外(至少对我来说)结果。



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>
&#13;
&#13;
&#13;

问题是:
1)为什么output1看起来与output2不相似(虽然它们的创建非常相似)? 2)是否有一种方法可以像array.push(obj)一样推送数组(输出方式是填充的)并获得像output1这样的结果(初始数组中的所有值都在那里)?

2 个答案:

答案 0 :(得分:1)

试试这个:

expect(results).to all(have_product_type(/^(A|B)$/'))
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> ...你正在引用相同的对象,因此它将包含最新的值......

答案 1 :(得分:1)

  

1)为什么output1看起来与output2不相似(虽然它们的创建非常相似)?

这与JavaScript中的closure有关。

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

因此,当您的作业全部完成并且您正在打印output2的内容时,您会发现它只是打印doc的值,这是

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

2)有没有一种方法可以像array.push(obj)一样推送数组(输出方式是填充的),得到像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); 
});