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

【问题讨论】:

  • 你的问题很不清楚你的意图。你能提供输出吗?
  • @ndugger 运行代码sn -p查看输出

标签: 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...您引用的是同一个对象,因此其中包含最新的值...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 2019-04-05
      • 2019-04-07
      • 2021-12-28
      • 2021-10-04
      相关资源
      最近更新 更多