2010-02-15 21 views
62

dado un cero simple basada, arreglo indexado numéricamente:¿Por qué 'para (var item in list)' con arrays se considera una mala práctica en JavaScript?

var list = ['Foo', 'Bar', 'Baz']; 

Muchas veces, he notado que cuando alguien sugiere bucle a través de las variables en una matriz de esta manera:

for(var item in list) { ... } 

... No hay casi ciertamente alguien que sugiere que eso es una mala práctica y sugiere un enfoque alternativo:

var count = list.length; 

for(var i = 0; i < count; i++) { 
    var item = list[i]; 
    ... 
} 

¿Cuál es el razonamiento para no usar la versión más simple de arriba y usar el segundo ejemplo en su lugar?

+0

Usted no está en bucle a través de los elementos, con ese bucle, que está bucle sobre las teclas/nombres de propiedades/Indizes. – Bergi

+2

También codificadores C en tophats victorianos que no comprenden los iteradores. Sin embargo, tenga en cuenta que está escupiendo claves, no valores. El formato for (;;) es más rápido, pero el 99% de las veces, realmente no importa. El tiempo de codificación es más caro que el tiempo de cálculo a menos que trabaje en megaproyectos o cosas con una necesidad genuina de optimización. – Shayne

Respuesta

76

En primer lugar, el orden del ciclo no está definido para un ciclo for...in, por lo que no hay garantía de que las propiedades se repitan en el orden que desee.

En segundo lugar, for...in itera sobre todas las propiedades enumerables de un objeto, incluidas las heredadas de su prototipo. En el caso de matrices, esto podría afectar a usted si su código o cualquier librería incluida en su perfil ha aumentado el prototipo de Array, que puede ser una cosa realmente útil para hacer:

Array.prototype.remove = function(val) { 
    // Irrelevant implementation details 
}; 

var a = ["a", "b", "c"]; 

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

// Logs 0, 1, 2, "remove" (though not necessarily in that order) 
+2

eso está bien siempre y cuando use 'hasOwnProperty' aunque -' para (var i en a) {if (a.hasOwnProperty (i)) console.log (i); } '-> 1 2 3 –

+9

Una sugerencia, cambia' sobre todas las propiedades' a 'sobre ** enumerable ** properties'. En las implementaciones más recientes de javascript, las propiedades se pueden definir con el atributo 'enumerable' establecido en' false'. Estas propiedades y propiedades de los objetos javascript incorporados no aparecerían en un 'for ... in'. –

+4

@Dimitar: De hecho, aunque una vez que haya agregado eso, el ciclo ha dejado de parecer más simple que un estilo C estándar para el ciclo. –

0

Añadir list.foo = bar; y tratar de utilizar simple for. Si no utiliza algunas bibliotecas (como prototypeJs) y no agrega ninguna propiedad nueva al objeto de matriz, puede usar la instrucción for simple.

1

Si utiliza para/in así, item enumera a través de valores de cadena "0", "1", ..., por lo que no son los objetos reales en la lista. Entonces, el 'elemento' en el primer fragmento se parece más al i en el segundo fragmento, no al item. Además, los valores de cadena se enumeran donde esperaría los números. Y te metes en problemas cuando tienes propiedades en la lista, como array.ID = "a123", ya que también se enumerarán.

Pero con estas desventajas, sigo pensando que la sintaxis es muy útil, si su equipo sabe lo que hace.

16

Velocidad?

for(..;..;..) bucle resultó ser 36 veces más rápido que for .. inwhen I tested it here.

Link courtesy this SO answer

+4

Lo leí mal ya que el bucle infinito es 36 veces más rápido que un bucle normal. Gracias por el enlace +1. –

+0

@Thomas Malentendido razonable: cuando se lee fuera de contexto. Reparado :) – Amarghosh

Cuestiones relacionadas