Precaución:
la pregunta todavía se aplica a los
for…of
bucles.> No usefor…in
para iterar sobre una matriz , úsela para iterar sobre las propiedades de un objeto. Dicho esto, esto
Entiendo que la for…in
sintaxis 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-in
bucle 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…in
itera 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 elforEach
mé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…of
bucle en lugar de afor…in
), no hay nada incorporado:manifestación
Si realmente
for…in
quisiera decir , enumerar propiedades, necesitaría un contador adicional.Object.keys(obj).forEach
podría funcionar, pero solo incluye propiedades propias ;for…in
incluye propiedades enumerables en cualquier parte de la cadena del prototipo.fuente
let
s sonvar
s con alcance de bloque.const
s no cambian%d
formatea un número entero y%s
formatea 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? Miarray
es 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.forEach
este método tiene unindex
parámetro que es el índice del elemento actual que se procesa en la matriz.fuente
break
que 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
eachWithIndex
que funciona con cualquier cosa iterable.También podría escribir una función similar
eachWithKey
que 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
?eachWithIndex
no satisface la interfaz iterable, que es el objetivo deSymbol.iterator
.eachWithIndex
para 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