2012-09-03 39 views
0

我使用的原型繼承陣列,以這樣的方式子類的JavaScript陣列打破快速列舉

MyArray = function() 
{ 
    Array.apply(this, arguments); 
}; 

MyArray.prototype = new Array(); 

全部按預期工作正常,我可以通過這種方式初始化「MYARRAY」實例:

var arr = new MyArray(); 
arr.push(1, 2, 3); 

問題是,快速列舉被打破了MYARRAY情況下,其實下面的循環:

for (var i in arr) 
{ 
    console.log(i); 
} 

打印:0,1,2,長度

實際上,該類的每個方法/屬性都包含在枚舉中。 在普通數組中,代碼只能打印0,1,2(這些數字是數組的索引)。

所以......我的問題是:如何通過保留快速枚舉來擴展Array?

ps:在Objective C中,爲了實現快速枚舉,你必須重寫一個方法......是否有一種特殊的方法可以在JavaScript中重寫?

注意:顯然我真正的「MyArray」實現稍有不同,但我發佈的代碼足以產生異常的快速枚舉循環。不要問我爲什麼要擴展數組,我有我的正當理由;)

+5

[你不能*真的*子類Array](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/)。此外,這不是JavaScript中的「快速枚舉」,實際上就Array實例而言,它最好稱爲「不正確的枚舉」:-) – Pointy

+1

(這是「不正確的」,因爲除此之外,甚至不能保證規範獲得編號屬性的順序。) – Pointy

+0

@Pointy你可以張貼您的評論作爲答案,以讓我接受它嗎? ;) – daveoncode

回答

3

數組元素永遠不要枚舉for (var x in obj),因爲它迭代對象的可枚舉屬性不僅僅是數組元素,正如你所看到的,可以包含數組元素之外的東西。此外,這種迭代方法不能保證以任何給定的順序返回屬性,所以你的數組元素可能沒有正確的順序。

在最新的瀏覽器中,您可以使用Object.defineProperties() method創建屬性並指定某個屬性是否可枚舉,但這並不意味着使用for (var x in obj)枚舉數組的元素永遠是正確的。我們應該總是使用這種形式來迭代數組元素:for (var i = 0, len = arr.length; i < len; i++)或像array.forEach(callback [, thisArg])這樣的內置迭代器。

+0

只是想知道,'while(arrlen--){...}'呢? –

+0

@JaredFarrish - 我的意圖是直接通過數字索引迭代的任何形式。一旦可以使用在兩個索引值之間迭代的任何形式的循環。 'while()'也可以,如果它迭代數字索引值並通過'.length'確定邊界。 – jfriend00

+0

我通常用於/ in來迭代「普通」數組,並且我沒有任何問題,返回的元素按正確的順序排列,沒有「額外屬性」返回......您能證明我的反面嗎? – daveoncode