forEach仅打印最后一个值,这是javascript中的典型闭包问题

时间:2017-10-18 11:02:57

标签: javascript foreach

我尝试使用这种方法,因为你通常如何解决任何关闭问题,但显然这对我不起作用。我尝试将其更改为letconst甚至箭头函数,但代码始终打印最后一个数组元素。

有谁能告诉我这里我做错了什么:



var data = [{
  "first_name": "John",
  "last_name": "Doe",
  "phone": "31227-5325"
}, {
  "first_name": "Jane",
  "last_name": "Campbell",
  "phone": "123123-5325"
}];

window.onload = function() {
  console.log('loaded....');
  data.forEach(function(elem, index) {

    let p = index;
    document.querySelector('#fname').innerHTML = '<td>' + data[p].first_name + '</td>';
    document.querySelector('#lname').innerHTML = '<td>' + data[p].last_name + '</td>';
    document.querySelector('#phone').innerHTML = '<td>' + data[p].phone + '</td>';

  })

}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-border">
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Phone</th>
    </tr>
  </thead>
  <tr class="tr1">
    <td id="fname"></td>
    <td id="lname"></td>
    <td id="phone"></td>
  </tr>

</table>
&#13;
&#13;
&#13;

http://jsbin.com/gasegeqila/1/edit?js,output

由于

4 个答案:

答案 0 :(得分:1)

您的问题是因为您在循环中设置了相同元素的值,因此只有最后一次迭代中设置的值可见。

您需要在循环中创建一个新行并在其中设置值,如下所示:

var data = [{
  "first_name": "John",
  "last_name": "Doe",
  "phone": "31227-5325"
}, {
  "first_name": "Jane",
  "last_name": "Campbell",
  "phone": "123123-5325"
}];

window.onload = function() {
  var tbody = document.querySelector('table tbody');
  
  data.forEach(function(elem, index) {
    var tr = document.createElement('tr');
    tr.innerHTML = `<td>${data[index].first_name}</td><td>${data[index].last_name}</td><td>${data[index].phone}</td>`;
    tbody.appendChild(tr);
  })
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-border">
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Phone</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

答案 1 :(得分:0)

编辑:

一种方法是分别创建行和单元格:

var row = table.insertRow(i + 1);

var cl1 = row.insertCell(0);
var cl2 = row.insertCell(1);
var cl3 = row.insertCell(2);

cl1.innerHTML = data[i].first_name;
cl2.innerHTML = data[i].last_name;
cl3.innerHTML = data[i].phone;

工作示例: https://jsfiddle.net/dkppcdtz/1/

答案 2 :(得分:0)

  

代码总是打印最后一个数组元素?

来自Docs

  

id全局属性定义唯一标识符(ID)   这在整个文件中必须是唯一的。

从你的剧本:

document.querySelector('#fname').innerHTML = ...;
document.querySelector('#lname').innerHTML = ...;
document.querySelector('#phone'). = .....

您总是用新的数据替换您的数据。因此,最后一个元素正在更新。

你可以像这样循环,

var table = document.querySelector('.table.table-border');

data.forEach(function(elem, index) {

    let p = index;
    let newRowHtml = '<tr><td>' + data[p].first_name + '</td>' +
                    '<td>' + data[p].last_name + '</td>' +
                    '<td>' + data[p].phone + '</td></tr>';


    table.insertAdjacentHTML('afterend', newRowHtml);

})

答案 3 :(得分:0)

您可以使用array#reduce创建行字符串,然后将生成的字符串添加到表体中。

&#13;
&#13;
var data = [{
  "first_name": "John",
  "last_name": "Doe",
  "phone": "31227-5325"
}, {
  "first_name": "Jane",
  "last_name": "Campbell",
  "phone": "123123-5325"
}];

window.onload = function() {
  console.log('loaded....');
  var row = data.reduce(function(str, elem, index) {
    let p = index;
    str += '<tr><td>' + data[p].first_name + '</td><td>' + data[p].last_name + '</td><td>' + data[p].phone + '</td></tr>';
    return str;
  }, '');
  document.querySelector('table tbody').innerHTML = row;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-border">
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Phone</th>
    </tr>
  </thead>
  <tbody class="tr1">
  </tbody>

</table>
&#13;
&#13;
&#13;