Javascript数组

时间:2015-05-03 08:16:12

标签: javascript arrays

为什么数组的length属性不能在for in循环中迭代?我有以下代码:

var a = new Array();
for (i in a) { 
    if (i === 'length') 
        alert(i) 
};

上述内容并未导致任何警报。但是,如果我改变长度'字符串到'克隆',引发警报。我不明白这一点,因为两者的长度都很长。和克隆'似乎是Array对象的成员,如下所示:

console.dir(a)

在搜索Google时,我只找到了使用hasOwnProperty方法的建议。这没有任何帮助,只会导致两种情况都没有发出警报。

1 个答案:

答案 0 :(得分:5)

Javascript中的for (i in a)结构列出了标记为enumerable的Javascript对象的属性。它列出了对象的所有可枚举属性,无论它们是直接在对象上还是通过原型继承。 ' enumerable`是一个属性的特定特征。您可以拥有可枚举或不可枚举的对象属性。

.length属性未标记为可枚举,因此未使用for (i in a)结构显示。如果您使用Object.defineProperty()自行创建属性,则可以控制可枚举属性(以及其他几个属性)。如果您只是直接添加属性而不使用Object.defineProperty()指定其自定义属性,则默认情况下该属性将是可枚举的。

For a variety of reasons,您永远不应该尝试使用for (i in a)结构迭代数组的元素。该结构明确地设计为列出Javascript对象的可枚举属性,该对象将包括所有Array元素,但也可能包括其他可枚举属性(正如您所见)。数组元素应枚举为:

for (var i = 0, len = array.length; i < len; i++) {
    // array[i]
}

array.forEach(function(val, index, array) {
    // code here
});

关于.clone的观察,这不是Array对象的标准属性。我猜测它可能已被某个第三方库添加到Array原型中,并且显然标记为可枚举,这解释了它在for (i in a)循环中显示的原因。

.hasOwnProperty()通常用于过滤原型上的属性,因此您只迭代直接应用于对象的属性(不是从原型继承),这解释了为什么它会过滤掉{{1属性(如果它在原型上)。

在任何情况下,如果您的目标是迭代数组的元素(而不是添加到Array对象的任何自定义属性),那么您应该使用上述两种迭代方法之一,然后您赢得了# t必须担心原型或Array对象本身上的.clone或其他可枚举属性。