He visto muchas preguntas que sugieren usar:
for (var i = 0; i < myArray.length; i++){ /* ... */ }
en vez de:
for (var i in myArray){ /* ... */ }
para matrices, debido a iteraciones inconsistentes ( ver aquí ).
Sin embargo, parece que no puedo encontrar nada que parezca preferir el bucle orientado a objetos:
myArray.forEach(function(item, index){ /* ... */ });
Lo que me parece mucho más intuitivo.
Para mi proyecto actual, la compatibilidad con IE8 es importante y estoy considerando usar el polyfill de Mozilla , sin embargo, no estoy 100% seguro de cómo funcionará.
- ¿Existen diferencias entre el bucle for estándar (el primer ejemplo anterior) y la implementación Array.prototype.forEach de los navegadores modernos?
- ¿Existe alguna diferencia entre las implementaciones de navegadores modernos y la implementación de Mozilla vinculada anteriormente (con especial atención a IE8)?
- El rendimiento no es un problema, solo la coherencia con las propiedades que se repiten.
javascript
arrays
for-loop
internet-explorer-8
iterator
Michael Lewis
fuente
fuente
break
salirforEach
. Pero una gran ventaja es crear un nuevo alcance con la función. Con el polyfill no deberías tener ningún problema (al menos no he encontrado ninguno).holes
dondeundefined
debería estar y otros métodos rotos, comoslice
yhasOwnProperty
wrt para objetos DOM tipo matriz. Mis pruebas yes5 shim
han demostrado que dichos métodos con calce cumplen con la especificación (no se probó el calzo de MDN).for
bucle, para eso essome
.Array.find()
para salir del bucle después de encontrar una primera coincidencia.Respuestas:
La diferencia más sustancial entre el
for
bucle y elforEach
método es que, con el primero, puedebreak
salir del bucle. Puede simularcontinue
simplemente regresando de la función pasada aforEach
, pero no hay forma de detener el bucle por completo.Aparte de eso, los dos logran efectivamente la misma funcionalidad. Otra diferencia menor involucra el alcance del índice (y todas las variables que lo contienen) en el ciclo for, debido a la elevación de variables.
// 'i' is scoped to the containing function for (var i = 0; i < arr.length; i++) { ... } // 'i' is scoped to the internal function arr.forEach(function (el, i) { ... });
Sin embargo, encuentro que
forEach
es mucho más expresivo: representa su intención de iterar a través de cada elemento de una matriz y le proporciona una referencia al elemento, no solo al índice. En general, todo se reduce al gusto personal, pero si puede usarloforEach
, le recomendaría usarlo.Hay algunas diferencias más sustanciales entre las dos versiones, específicamente con respecto al rendimiento. De hecho, el bucle for simple funciona considerablemente mejor que el
forEach
método, como lo demuestra esta prueba jsperf .Si tal actuación es necesaria o no para usted, depende de usted decidir y, en la mayoría de los casos, preferiría la expresividad a la velocidad. Esta diferencia de velocidad probablemente se deba a las diferencias semánticas menores entre el bucle básico y el método cuando se opera en matrices dispersas, como se indica en esta respuesta .
Si no necesita el comportamiento de
forEach
y / o necesita salir del ciclo temprano, puede usar Lo-Dash_.each
como alternativa, que también funcionará en todos los navegadores. Si está utilizando jQuery, también proporciona un similar$.each
, solo tenga en cuenta las diferencias en los argumentos pasados a la función de devolución de llamada en cada variación.(En cuanto al
forEach
polyfill, debería funcionar en navegadores más antiguos sin problemas, si elige seguir esa ruta).fuente
each
no se comportan de la misma manera que la especificación ECMA5 deforEach
, tienden a tratar todas las matrices como densas (para evitar errores de IE, siempre que lo sepa). De lo contrario, puede ser un "gotcha". Como referencia github.com/es-shims/es5-shim/issues/190Array.prototype.some
que se repetirá hasta que devuelva un valor verdadero o hasta que haya recorrido completamente la matriz.Array.prototype.every
es similar a,Array.prototype.some
pero se detiene si devuelve un valor falso.Array.prototype.forEach
con alguna versión no compatible tendría el potencial de romper tantas bibliotecas que evitarlo por esa razón no ayudaría, de todos modos.Puede usar su función foreach personalizada, que funcionará mucho mejor que Array.forEach
Debería agregar esto una vez a su código. Esto agregará una nueva función a la matriz.
function foreach(fn) { var arr = this; var len = arr.length; for(var i=0; i<len; ++i) { fn(arr[i], i); } } Object.defineProperty(Array.prototype, 'customForEach', { enumerable: false, value: foreach });
Entonces puede usarlo en cualquier lugar como Array.forEach
[1,2,3].customForEach(function(val, i){ });
La única diferencia es que es 3 veces más rápido. https://jsperf.com/native-arr-foreach-vs-custom-foreach
ACTUALIZACIÓN: En la nueva versión de Chrome, se mejoró el rendimiento de .forEach (). Sin embargo, la solución puede ofrecer un rendimiento adicional en otros navegadores.
fuente
Muchos desarrolladores (por ejemplo, Kyle Simpson) sugieren usarlo
.forEach
para indicar que la matriz tendrá un efecto secundario y.map
para funciones puras.for
Los bucles se adaptan bien como una solución de propósito general para un número conocido de bucles o cualquier otro caso que no encaja, ya que es más fácil de comunicarse debido a su amplio soporte en la mayoría de los lenguajes de programación.p.ej
/* For Loop known number of iterations */ const numberOfSeasons = 4; for (let i = 0; i < numberOfSeasons; i++) { //Do Something } /* Pure transformation */ const arrayToBeUppercased = ['www', 'html', 'js', 'us']; const acronyms = arrayToBeUppercased.map((el) => el.toUpperCase)); /* Impure, side-effects with .forEach */ const acronymsHolder = []; ['www', 'html', 'js', 'us'].forEach((el) => acronymsHolder.push(el.toUpperCase()));
En cuanto a las convenciones, esto parece lo mejor, sin embargo, la comunidad realmente no se ha conformado con una convención sobre los
for in
bucles de protocolo de iteración más nuevos . En general, creo que es una buena idea seguir los conceptos de FP que la comunidad de JS parece estar abierta a adoptar.fuente