数组元素与属性?

时间:2011-01-07 17:23:02

标签: javascript

所以要跟进上一个问题;

由于使用属性的动态功能和使用

进行迭代
for(var key in array)

我已经非常喜欢尝试枚举数组并按数字迭代。

仅仅.pushing元素和设置为属性的优点和缺点是什么?

除了明显的识别差异外。

2 个答案:

答案 0 :(得分:7)

缩短
从不在数组上使用for in,它极其缓慢且容易失败。

解释

好吧,虽然JavaScript中的ArrayObject,但没有充分的理由使用for in循环来迭代它。事实上,for in上使用Array 反对有很多很好的理由。

虽然起初看起来似乎是一个不错的选择,但是要将某些速度与for in结构的可读性进行交换,这会对性能产生主要影响。

for in确实迭代了Array的索引。但它也会遍历原型链。因此,必须使用hasOwnProperty以确保过滤掉不需要的属性,并且如果在阵列上碰巧定义了任何其他属性,它们仍将通过此过滤器。

Array.prototype.bar = 1; // poisoning the Object.prototype, NEVER do this
var foo = [1, 2, 3];
for(var i in foo) {
    console.log(i);
}

上述代码导致打印出“索引”012 bar

使用hasOwnProperty进行过滤

Array.prototype.bar = 1; // poisoning the Object.prototype, NEVER do this
var foo = [1, 2, 3];
foo.blub = 2;
for(var i in foo) {
    if (foo.hasOwnProperty(i)) {
        console.log(i);
    }
}

以上代码结果现在打印“索引”012 blub,您无法过滤掉{ {1}}以任何有意义的方式,除非您验证密钥是正整数。

效果

现在,将遍历blub的原型的慢速特性与for in结合起来会导致性能下降,直至 20x

因此,如果你想在JavaScript中迭代hasOwnProperty总是使用经典的Array循环结构。

for

正如您所看到的,上面的示例中还有一个额外的问题。这是通过var list = [1, 2, 3, 4, 5, ...... 100000000]; for(var i = 0, l = list.length; i < l; i++) { console.log(list[i]); } 缓存长度。

虽然在数组本身上定义了l = list.length属性,但在每次迭代中进行查找仍然存在开销。虽然最近的JavaScript引擎可能在这种情况下应用优化,但是人们永远无法确定这些优化是否真正到位,也无法确定它们是否达到了上述缓存的速度。事实上,省略缓存可能会导致性能下降,直至 2x (在旧引擎中甚至更多)。

答案 1 :(得分:3)

最重要的区别是枚举将列出所有属性,甚至是原型链中的属性。例如(这并不罕见):

Array.prototype.isEmpty = function() {
    return this.length == 0;
}

var myArray = [2, 3, 5];

for(var key in myArray) {
    console.log(key);
}

将列出

0
1
2
isEmpty

isEmpty很可能不是你想要的那个枚举。

此外,length属性仅受数字索引的影响。在这种情况下,它不相关,因为您要枚举元素,但要记住一些事项。

var a = [];

a["4"] = "test";
a.length; // 5

a[10] = "ing";
a.length = 11;