2015-05-03 48 views
0

爲什麼length數組的屬性沒有在for in循環中迭代完成?我有以下代碼:Javascript中的長度屬性數組

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

以上不會導致任何警報。但是,如果將「長度」字符串更改爲「克隆」,則會引發警報。我不明白這一點,因爲這兩個「長度」和「克隆」似乎是數組對象的成員,可略見一斑:

console.dir(a) 

搜索谷歌,我只發現使用hasOwnProperty建議方法。這沒有幫助,只會導致兩種情況都不會發出警報。

+0

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Enumerable_attribute – zerkms

回答

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)結構迭代Array的元素。該結構被明確地設計爲列出一個Javascript對象的可枚舉屬性,該對象將包含所有數組元素,但也可能包含其他可枚舉屬性(如您所見)。

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

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

至於你的觀察約.clone,這不是一個數組對象的標準屬性:數組元素應該被列舉。我猜測它可能已經被一些第三方庫添加到了數組原型中,並且它顯然被標記爲可枚舉,這就解釋了爲什麼它會在你的循環中顯示。


.hasOwnProperty()通常用來過濾掉所有的原型屬性,因此您只能遍歷被直接應用到這解釋了爲什麼它會過濾掉.clone屬性(對象(而不是從原型繼承。)性質如果它在原型上)。在任何情況下,如果你的目標是迭代一個數組的元素(而不是任何添加到數組對象的自定義屬性),那麼你應該使用上述兩種迭代方法之一,然後你不會不得不擔心.hasOwnProperty()或原型或Array對象本身上的其他可枚舉屬性。

+0

感謝您的快速回復。我試過檢查: 'a。propertyIsEnumerable('clone')' and 'a.propertyIsEnumerable('length')' 但都返回false。如果你上面解釋的是真的,那麼'克隆'不應該被迭代嗎? – Roy

+0

@Roy - 你必須告訴我們你正在使用的具體代碼以及'clone'屬性是如何讓我們看到你的情況到底發生了什麼。如果你可以在jsFiddle中重新創建,我們可以看看它。根據[MDN上的此描述](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable)'.propertyIsEnumerable()'將與'for(i在a)'只有當財產不在原型上時,這可能就是你看到分歧的原因。 – jfriend00

+0

沒關係,改變了一些東西,現在沒有任何警報提出Array的任何屬性。 '''var a = new Array(); for(i in a){ alert(i) }; ''' 無論如何,由zerkms提供的鏈接證實您的答案是正確的。謝謝您的幫助。 – Roy