将嵌套的JavaScript循环重构为CoffeeScript理解

时间:2014-06-08 01:15:13

标签: javascript coffeescript list-comprehension nested-loops

我有以下JavaScript,我想将其翻译为CoffeeScript:

function initPage() {
  var tr = document.getElementsByTagName('tr')[0];
  labs.forEach(function(lab) {
    var td = document.createElement('td');

    // Create a header for each lab.
    var h2 = document.createElement('h2');
    h2.innerHTML = lab.name;
    td.appendChild(h2);

    // Create a div for each machine in a given lab.
    for(i = lab.first; i <= lab.last; i++) {
      var machine = ((i < 10) ? "0" : "") + i;
      var div = document.createElement('div');
      div.setAttribute('id', lab.name + "-" + machine);
      div.setAttribute('class', 'Grey');
      div.innerHTML = machine;
      td.appendChild(div);
    }

    // Append the new table data element to the table row.
    tr.appendChild(td);
  });
}

现在我的CoffeeScript翻译看起来像这样:

initPage = () ->
  tr = document.getElementsByTagName('tr')[0]
  labs.forEach (lab) ->
    td = document.createElement 'td'

    # Create a header for each lab.
    h2 = document.createElement 'h2'
    h2.innerHTML = lab.name
    tr.appendChild h2

    # Create a div for a machine given the machine number
    createDiv = (i) ->
      machine = if i < 10 then "0#{i}" else "#{i}"
      div = document.createElement 'div'
      div.setAttribute 'id', "#{lab.name}-#{machine}"
      div.setAttribute 'class', 'Grey'
      div.innerHTML = machine
      td.appendChild div

    # Create a div for each machine in a given lab
    createDiv machine for machine in [lab.first..lab.last]

    # Append the new table data element to the table row.
    tr.appendChild td

是否有更好,更惯用的方法为每个实验室创建div?最好避免使用createDiv函数并执行以下操作:

for i in [lab.first..lab.last]
  machine = if i < 10 then "0#{i}" else "#{i}"
  div = document.createElement 'div'
  div.setAttribute 'id', "#{lab.name}-#{machine}"
  div.setAttribute 'class', 'Grey'
  div.innerHTML = machine
  td.appendChild div

CoffeeScript language reference

  

你将在CoffeeScript中编写的大多数循环都是对数组,对象和范围的理解。

  

理解应该能够处理大多数你会使用循环的地方,每个/ forEach,map或select / filter

我对列表推导的想法不熟悉,并希望确保我正在以适当利用CoffeeScript优势的方式翻译此代码。

2 个答案:

答案 0 :(得分:1)

  

避免使用createDiv函数并内联它会更好吗?

是的,这个功能看起来有点多余。

  

我对列表推导的想法不熟悉,并希望确保我以适当的方式翻译此代码

list comprehensions的目标是建立新的列表,例如mapfilter会这样做。对于经常使用的循环或(不恰当地)forEach,手动push到数组。

但是,您的目标不是创建数组,而只是创建DOM元素。理解在这里没有帮助,你需要将它们用作循环来执行副作用。

答案 1 :(得分:0)

JavaScript的规则#4354444:不要在循环中声明函数,它通常对性能有害。只需返回div或将td作为参数传递,并将函数移出两个循环。

这里有几个重构机会。 1)提取元素创建方法,如createEl(tag, {attrs})。 2)使用某种模板材料

(实际上,如果你总是将它们附加到现有的DOM元素中,那么构建dom音符通常会更慢。如果你想手工制作它们,最好使用文档片段)

无论如何,你无法避免使用for循环。理解非常有用,但不是完美的解决方案。