@Wibowit:
for..in
służy do iterowania się po własnościach obiektu. Iteruje po wszystkich "iterowalnych" (enumerable) własnościach obiektu, własnych lub odziedziczonych. Tablice, oprócz własności będących indeksami, mają też własność .length
, ale ona nie jest enumerable, więc w for..in by nie wyszła.
Jeśli jednak ktoś nieopatrznie dodałby coś do prototypu tablic, np. funkcję .isEmpty()
, bo chciałby mieć taką funkcję we wszystkich tablicach...
// uwaga, zły kod! (pod wieloma względami)
Array.prototype.isEmpty = function() {
return this.length === 0;
};
To w naszym for..in po dowolnej tablicy dostalibyśmy już, oprócz indeksów, również ciąg isEmpty
. Bo funkcja isEmpty
dodana w ten sposób jest enumerable. Rozszerzanie prototypów obiektów wbudowanych nie jest najlepszym pomysłem, ale nawet niektóre biblioteki tak robią.
Poza tym, for..in nie gwarantuje kolejności odwiedzania elementów.
Zwykle jednak przyfarcimy i elementy będą odwiedzane w kolejności dodania, a w tablicy zdefiniujemy je wszystkie naraz, więc kolejność będzie właściwa. Co więcej, nikt nie powinien rozszerzyć Array.prototype
ani nadrzędnego Object.prototype
, więc wszystko może nam niby zadziałać. Ale gdy np. usuniemy jakąś wartość z tablicy, a potem ją dodamy, IE może się już zgubić jeśli chodzi o kolejność iteracji.
for..in używa się do iterowania po wszystkich własnościach obiektu. Zwykle chodzi nam o własności, których nazwy nie są liczbami (indeksami). Często przydaje się to w tzw. refleksji. I najczęściej trzeba użyć .hasOwnProperty()
by uchronić się przed iterowaniem się przez własności odziedziczone z łańcuchu prototypów.