¿Crees que hay una gran diferencia en ... en y para bucles? ¿Qué tipo de "para" prefiere usar y por qué?
Digamos que tenemos una matriz de matrices asociativas:
var myArray = [{'key': 'value'}, {'key': 'value1'}];
Entonces podemos iterar:
for (var i = 0; i < myArray.length; i++)
Y:
for (var i in myArray)
No veo una gran diferencia. ¿Hay algún problema de rendimiento?
javascript
andrii
fuente
fuente
myArray.forEach(callback[, thisarg])
.if(myArray.hasOwnProperty(i)){true}
['foo', 'bar', 'baz'].forEach(function(element, index, array){ console.log(element, index, array); });
está bien usar casi en todas partes, excepto en IE8, y es, con mucho, la sintaxis más elegantefor...of
declaración en ECMAScript 6 , por ejemplo:for (let i of myArray) console.log(i);
Respuestas:
La elección debe basarse en qué idioma se entiende mejor.
Una matriz se itera usando:
Un objeto que se usa como una matriz asociativa se itera usando:
A menos que tenga razones devastadoras, manténgase en el patrón de uso establecido.
fuente
for
, no evaluar una longitud cada vez en el bucle.i < l
, noi < a
, en tu condición de bucle for.Douglas Crockford recomienda en JavaScript: The Good Parts (página 24) para evitar el uso de la
for in
declaración.Si utiliza
for in
para recorrer los nombres de propiedad en un objeto, los resultados no están ordenados. Peor: puede obtener resultados inesperados; incluye miembros heredados de la cadena del prototipo y el nombre de los métodos.Todo menos las propiedades se pueden filtrar con
.hasOwnProperty
. Este ejemplo de código hace lo que probablemente quería originalmente:fuente
name
variable: de lofor(var name in object)...
contrario, si ese código está dentro de una función, por ejemplo, laname
variable termina siendo una propiedad del objeto global (una asignación a un identificador no declarado lo hace), también en el nuevo ECMAScript 5 Modo estricto, ese código arrojará unReferenceError
.FYI - Usuarios de jQuery
El
each(callback)
método de jQuery usa elfor( ; ; )
bucle por defecto, yfor( in )
solo lo usará si la longitud esundefined
.Por lo tanto, diría que es seguro asumir el orden correcto al usar esta función.
Ejemplo :
La desventaja de usar esto es que si está haciendo alguna lógica que no sea de UI, sus funciones serán menos portables a otros marcos. La
each()
función probablemente esté mejor reservada para su uso con los selectores jQuery y, de lofor( ; ; )
contrario, sería aconsejable.fuente
existen diferencias de rendimiento según el tipo de bucle que use y en qué navegador.
Por ejemplo:
es casi el doble de rápido en algunos navegadores que:
Sin embargo, a menos que sus matrices sean ENORMES o las repita constantemente, todas son lo suficientemente rápidas. Dudo seriamente que el bucle de matriz sea un cuello de botella en su proyecto (o para cualquier otro proyecto)
fuente
for(var i = myArray.length; i--;)
Tenga en cuenta que el método nativo Array.forEach ahora es ampliamente compatible .
fuente
Respuesta actualizada para la versión actual de 2012 de todos los principales navegadores: Chrome, Firefox, IE9, Safari y Opera admiten la matriz nativa de ES5. Para cada uno.
A menos que tenga alguna razón para admitir IE8 de forma nativa (teniendo en cuenta que se puede proporcionar ES5-shim o Chrome frame a estos usuarios, lo que proporcionará un entorno JS adecuado), es más sencillo usar la sintaxis adecuada del lenguaje:
La documentación completa de array.forEach () está en MDN.
fuente
Los dos no son lo mismo cuando la matriz es escasa.
fuente
Usando forEach para saltear la cadena del prototipo
Solo un apéndice rápido a la respuesta de @ nailer anterior , usar forEach con Object.keys significa que puede evitar iterar sobre la cadena del prototipo sin tener que usar hasOwnProperty.
fuente
En segundo lugar, creo que debe elegir el método de iteración según sus necesidades. Te sugeriría que en realidad nunca recorras el nativo
Array
con lafor in
estructura. Es mucho más lento y , como Chase Seibert señaló en este momento, no es compatible con el marco Prototype.Hay un excelente punto de referencia en diferentes estilos de bucle que debe tener en cuenta si trabaja con JavaScript . No haga optimizaciones tempranas, pero debe mantener esas cosas en algún lugar detrás de su cabeza.
Lo usaría
for in
para obtener todas las propiedades de un objeto, lo que es especialmente útil al depurar sus scripts. Por ejemplo, me gusta tener esta línea a mano cuando exploro objetos desconocidos:Vuelca el contenido de todo el objeto (junto con los cuerpos de los métodos) en mi registro de Firebug. Muy manejable.
fuente
Aquí hay algo que hice.
así es como lo usaría
, funcionará en matrices y objetos (como una lista de elementos HTML)
Acabo de hacer esto, así que estoy abierto a sugerencias :)
fuente
Usaría los diferentes métodos según cómo quisiera hacer referencia a los elementos.
Use foreach si solo quiere el artículo actual.
Úselo si necesita un indexador para hacer comparaciones relativas. (Es decir, ¿cómo se compara esto con el elemento anterior / siguiente?)
Nunca he notado una diferencia de rendimiento. Esperaría hasta tener un problema de rendimiento antes de preocuparme por ello.
fuente
Con for (var i en miMatriz) puede bucle sobre objetos también, que contendrá el nombre de la clave y se puede acceder a la propiedad a través de miMatriz [i] . Además, cualquier método que haya agregado al objeto también se incluirá en el bucle, es decir, si usa un marco externo como jQuery o prototype, o si agrega métodos para objetar prototipos directamente, en un punto apuntaré a Esos métodos.
fuente
¡Cuidado!
Si tiene varias etiquetas de script y está buscando información en los atributos de la etiqueta, por ejemplo, debe usar la propiedad .length con un bucle for porque no es una matriz simple sino un objeto HTMLCollection.
https://developer.mozilla.org/en/DOM/HTMLCollection
Si usa la declaración foreach para (var i en su Lista), devolverá protecciones y métodos de la colección HTMLC en la mayoría de los navegadores.
Incluso si getElementsByTagName devuelve una NodeList, la mayoría de los navegadores devuelven una colección HTMLC: https://developer.mozilla.org/en/DOM/document.getElementsByTagName
fuente
For in loops on Arrays no es compatible con Prototype. Si cree que podría necesitar usar esa biblioteca en el futuro, tendría sentido atenerse a los bucles.
http://www.prototypejs.org/api/array
fuente
He visto problemas con el "para cada uno" usando objetos y prototipos y matrices
entiendo que el para cada uno es para propiedades de objetos y NO para matrices
fuente
Si realmente quieres acelerar tu código, ¿qué hay de eso?
es algo así como tener la lógica while dentro de la instrucción for y es menos redundante. Firefox también tiene Array.forEach y Array.filter.
fuente
Un código más corto y mejor según jsperf es
fuente
Use el Array (). ForEach loop para aprovechar el paralelismo
fuente
Array.prototype.forEach
lo que no ejecutará varias llamadas a la devolución de llamada en paralelo.para (;;) es para matrices : [20,55,33]
for..in es para objetos : {x: 20, y: 55: z: 33}
fuente
¡¡¡Ten cuidado!!! Estoy usando Chrome 22.0 en Mac OS y tengo problemas con cada sintaxis.
No sé si esto es un problema del navegador, un problema de JavaScript o algún error en el código, pero es MUY extraño. Fuera del objeto funciona perfectamente.
fuente
Hay una diferencia importante entre ambos. El for-in itera sobre las propiedades de un objeto, por lo que cuando el caso es una matriz, no solo iterará sobre sus elementos, sino también sobre la función "eliminar" que tiene.
Podrías usar el for-in con un
if(myArray.hasOwnProperty(i))
. Aún así, al iterar sobre matrices, siempre prefiero evitar esto y simplemente usar la instrucción for (;;).fuente
Aunque ambos son muy parecidos, hay una pequeña diferencia:
en este caso el resultado es:
NORMA PARA LAZO:
ARRAY [0] = A
ARRAY [1] = B
ARRAY [2] = C
mientras que en este caso la salida es:
FOR-IN LOOP:
ARRAY [1] = B
ARRAY [2] = C
ARRAY [10] = D
ARRAY [ABC] = 123
fuente
La instrucción for in permite recorrer los nombres de todas las propiedades de un objeto. Desafortunadamente, también recorre todos los miembros que fueron heredados a través de la cadena de prototipos. Esto tiene el efecto secundario negativo de servir funciones de método cuando el interés está en los miembros de datos.
fuente