Pro tento test používám Google Chrome:
Na rozdíl od intuice první smyčka upozorní „řetězec“ třikrát, zatímco druhá smyčka třikrát „číslo“.
numarray = [1, 2, 3]; //for-each loop for(num in numarray) alert(typeof(num)); // Standard loop for(i=0; i<numarray.length; i++) alert(typeof(numarray[i]));
Čekal jsem, že obě smyčky upozorní „číslo“ třikrát. Jak je první smyčka implementována v JavaScriptu? Jinými slovy, pokud for-each je syntaktický cukr, jaký je jeho ekvivalent při použití standardní smyčky?
Existuje také nějaký způsob, jak iterovat jmenný prostor objektu pomocí standardní smyčky? Chci se dotknout všech metod a atributů některých objektů pomocí smyčky druhého druhu.
Odpověď
Důvod, proč se vám v první smyčce vrací „řetězec“, je num
odkazuje na index pole , nikoli hodnotu numarray
u toho indexu. Zkuste změnit první smyčku na upozornění num
místo typeof num
a uvidíte, že vyplivne 0, 1 a 2, což jsou indexy, nikoli hodnoty vašeho pole.
Když použijete for in
smyčky, iterujete vlastnosti objektu, což není přesně ekvivalentní for
smyčka ve vašem druhém příkladu. Pole v JavaScriptu jsou ve skutečnosti pouze objekty se sekvenčními čísly jako názvy vlastností. Jsou považovány za řetězce až do typeof
je znepokojen.
Upravit:
Jak zdůrazňuje Matthew, při použití for in
není zaručeno, že položky v poli získáte v jakémkoli konkrétním pořadí. smyčky a částečně z tohoto důvodu se nedoporučuje iterovat pole tímto způsobem.
filip-fku se ptá, kdy by bylo užitečné použít for in
vzhledem k tomuto chování. Jedním z příkladů je, když mají význam samotná jména vlastností, což ve skutečnosti není případ indexů pole. Například:
var myName = { first: 'Jimmy', last: 'Cuadra' }; for (var prop in myName) { console.log(prop + ': ' + myName[prop]); } // prints: // first: Jimmy // last: Cuadra
Za zmínku také stojí for in
smyčky budou také iterovat prostřednictvím vlastností řetězce prototypu objektu. Z tohoto důvodu byste obvykle chtěli vytvořit for in
takto smyčka:
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { // do something } }
Tím se zkontroluje, zda vlastnost byla definována samotným objektem a ne objektem, který dědí prostřednictvím řetězce prototypu.