Precaución:
la pregunta todavía se aplica a los
for…ofbucles.> No usefor…inpara iterar sobre una matriz , úsela para iterar sobre las propiedades de un objeto. Dicho esto, esto
Entiendo que la for…insintaxis básica en JavaScript se ve así:
for (var obj in myArray) {
// ...
}
Pero, ¿cómo obtengo el contador / índice de bucle ?
Sé que probablemente podría hacer algo como:
var i = 0;
for (var obj in myArray) {
alert(i)
i++
}
O incluso los buenos viejos:
for (var i = 0; i < myArray.length; i++) {
var obj = myArray[i]
alert(i)
}
Pero prefiero usar el for-inbucle más simple . Creo que se ven mejor y tienen más sentido.
¿Hay una manera más simple o más elegante?
En Python es fácil:
for i, obj in enumerate(myArray):
print i
javascript
for-loop
foreach
counter
hobbes3
fuente
fuente

alert(obj)?Respuestas:
for…initera sobre nombres de propiedades, no valores, y lo hace en un orden no especificado (sí, incluso después de ES6). No debe usarlo para iterar sobre matrices. Para ellos, existe elforEachmétodo de ES5 que pasa tanto el valor como el índice a la función que le asigna:O ES6
Array.prototype.entries, que ahora es compatible con las versiones actuales del navegador:Sin embargo, para iterables en general (donde usaría un
for…ofbucle en lugar de afor…in), no hay nada incorporado:manifestación
Si realmente
for…inquisiera decir , enumerar propiedades, necesitaría un contador adicional.Object.keys(obj).forEachpodría funcionar, pero solo incluye propiedades propias ;for…inincluye propiedades enumerables en cualquier parte de la cadena del prototipo.fuente
lets sonvars con alcance de bloque.consts no cambian%dformatea un número entero y%sformatea una cadena. Se basan en printf . Una especificación está en progreso en console.spec.whatwg.org/#formatter .En ES6, es bueno usar para - de bucle. Puede obtener un índice de esta manera
Tenga en cuenta que
Array.entries()devuelve un iterador , que es lo que le permite trabajar en el ciclo for-of; no confunda esto con Object.entries () , que devuelve una matriz de pares clave-valor.fuente
entries()es devolver un objeto vacío:{}. ¿Alguna idea de por qué sería eso? Miarrayes una matriz de objetos.Object.entries(array)lugar dearray.entries()next()método que devolverá entradas posteriores en la matriz cada vez que se lo llame. No hay datos (visibles) en él; obtienes los datos en el objeto subyacente llamandonext(), lo que a menudo se hace detrás de escena. cc @tonygQué tal esto
Donde
array.forEacheste método tiene unindexparámetro que es el índice del elemento actual que se procesa en la matriz.fuente
breakque no está disponible.Solución para colecciones de matriz pequeña:
arr - ARRAY, obj - CLAVE del elemento actual, i - CONTADOR / ÍNDICE
Aviso: las teclas de método () no están disponibles para IE versión <9, debe usar el código Polyfill . https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
fuente
var i = 0;yi++;es más corto y más eficiente. Además, no funciona para propiedades enumerables que no son propiedades propias.For-in-loops itera sobre las propiedades de un objeto. No los use para matrices, incluso si a veces funcionan.
Las propiedades de los objetos no tienen índice, son todas iguales y no es necesario ejecutarlas en un orden determinado. Si desea contar las propiedades, deberá configurar el contador adicional (como lo hizo en su primer ejemplo).
bucle sobre una matriz:
recorrer un objeto:
fuente
(var i=0; i<a.length; i++)que se desperdicia recursos. Uso(var i=0, var len = a.length; i<len; i++)var i=0; i<a.length; i++)de todos modos es el patrón de bucle estándar que está optimizado por cada motor javascript decente.var i=0; i<a.length; i++es la mejor práctica.Como otros han dicho, no deberías usar for..in para iterar sobre una matriz.
Si desea una sintaxis más limpia, puede usar forEach:
Si desea utilizar este método, asegúrese de incluir la cuña ES5 para agregar compatibilidad con navegadores más antiguos.
fuente
Respuesta dada por rushUp es correcta pero esto será más conveniente
fuente
Aquí hay una función
eachWithIndexque funciona con cualquier cosa iterable.También podría escribir una función similar
eachWithKeyque funcione con objetos usandofor...in.Lo bueno de los generadores es que son flojos y pueden tomar el resultado de otro generador como argumento.
fuente
Esa es mi versión de un iterador compuesto que produce un índice y cualquier valor pasado de la función del generador con un ejemplo de búsqueda primaria (lenta):
fuente
eachWithIndex[Symbol.iterator]lugar de solo una funcióneachWithIndex?eachWithIndexno satisface la interfaz iterable, que es el objetivo deSymbol.iterator.eachWithIndexpara aceptar iterable y devolver un iterativo compuesto cerrado.Además de las muy buenas respuestas que todos publicaron, quiero agregar que la solución más eficiente es el ES6
entries. Parece contradictorio para muchos desarrolladores aquí, así que creé este perf benchamrk .Es ~ 6 veces más rápido. Principalmente porque no necesita: a) acceder a la matriz más de una vez y, b) emitir el índice.
fuente