在JavaScript中访问对象成员的有效方法

时间:2013-12-17 16:16:49

标签: javascript object performance

我的问题在某种程度上与this有关,但它仍然涉及一些关键的差异。

所以在这里,我有以下代码;

for(var i = 0; i < someObj.children[1].listItems.length; i++)
{
    doSomething(someObj.children[1].listItems[i]);

    console.log(someObj.children[1].listItems[i]);
}

VS

var i = 0,
    itemLength = someObj.children[1].listItems.length,
    item;

for(; i < itemLength; i++)
{
    item = someObj.children[1].listItems[i];
    doSomething(item);

    console.log(item);
}

现在,这是我在 ExtJS 中制作的企业Web应用程序中处理的代码的非常小示例部分。现在在上面的代码中,与第一个示例相比,第二个示例显然更具可读性和清晰度。 但是当我以类似的方式减少对象查找次数时,是否有任何性能提升?

我问这个场景,在循环中会有更多的代码访问对象深处的成员,迭代本身会发生~1000次,浏览器从IE8变为最新的Chrome。

3 个答案:

答案 0 :(得分:5)

没有明显的区别,但是对于性能和可读性,以及它看起来像实时nodeList这一事实,如果您要更改它,它应该反向迭代:

var elems = someObj.children[1].listItems;

for(var i = elems.length; i--;) {
    doSomething(elems[i]);
    console.log(elems[i]);
}

答案 1 :(得分:1)

性能提升取决于列表的大小。

缓存长度通常更好(第二种情况),因为每次循环都不会评估someObj.children[1].listItems.length,因为它是在第一种情况下。

如果顺序无关紧要,我喜欢这样循环:

var i;

for( i = array.length; --i >= 0; ){
  //do stuff
}

答案 2 :(得分:0)

缓存对象属性查找将导致性能增益,但其范围基于查找的迭代和深度。当您的JS引擎评估object.a.b.c.d之类的内容时,涉及的工作量多于仅仅评估d。您可以通过在循环外缓存其他属性查找来提高第二种情况的效率:

var i = 0,
    items = someObj.children[1].listItems,
    itemLength = items.length,
    item;

for(; i < itemLength; i++) {
    item = items[i];
    doSomething(item);

    console.log(item);
}

当然,最好的方法是jsperf