Javascript数组中的length属性

Roy*_*Roy 0 javascript arrays

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

var a = new Array();
for (i in a) { 
    if (i === 'length') 
        alert(i) 
};
Run Code Online (Sandbox Code Playgroud)

以上内容不会产生任何警报.但是,如果我将'length'字符串更改为'clone',则会引发警报.我不明白这一点,因为'length'和'clone'似乎都是Array对象的成员,可以通过以下方式看出:

console.dir(a)
Run Code Online (Sandbox Code Playgroud)

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

jfr*_*d00 5

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

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

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

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

要么

array.forEach(function(val, index, array) {
    // code here
});
Run Code Online (Sandbox Code Playgroud)

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


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

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