从节点列表转换时的for循环设置长度变量

时间:2009-05-13 11:13:50

标签: javascript

唷!这是一个很长的头衔。

我正在为Web开发人员阅读WROX的专业JavaScript书籍,我看到了这个示例代码,我只是想知道这是否是最佳实践:

function convertToArray(nodes) {
   array = new Array();
   for (var i=0, len=nodes.length; i < len; i++) {
      array.push(nodes[i]);
   }
   return array;
}

让我摸不着头脑的是“len = nodes.length”。我认为for循环中的第一句只运行一次是错误的吗?您是否有理由在运行之前将变量(len)设置为nodeList的长度?你会这样做到普通数组吗?

由于

2 个答案:

答案 0 :(得分:6)

这是出于性能原因。由于以下几个原因,局部变量更快:

  • 需要在循环中始终访问长度,每次迭代一次;
  • 局部变量查找比成员查找更快;
  • 如果nodes是一个数组,那么.length是一个神奇的属性,可能需要比成员变量更长的时间来检索。
  • 如果nodes是ActiveX对象,则.length可能会导致对对象的方法调用,因此这是所有操作中最昂贵的操作。

答案 1 :(得分:3)

虽然我们正在讨论微优化,但以下情况应该更快:

function convertToArray(nodes) {
    var i = nodes.length,
        array = new Array(i); // potentially faster than `array = []`
                              //  --  see comments

    while(i--)
        array[i] = nodes[i];

    return array;
}

它需要少一个局部变量,使用while而不是for循环,并使用数组赋值而不是函数调用push()

另外,因为我们正在倒计时我们预先分配数组的槽,所以每次迭代步骤都不需要更改数组的长度,但只在第一个上/ DEL>