En los documentos de MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
La for...of
construcción se describe para poder iterar sobre objetos "iterables". Pero, ¿existe una buena forma de decidir si un objeto es iterable?
Intenté encontrar propiedades comunes para matrices, iteradores y generadores, pero no pude hacerlo.
Aparte de hacer un for ... of
bloque de prueba y comprobar si hay errores de tipo, ¿hay una forma limpia de hacer esto?
javascript
Simonzack
fuente
fuente
iterator()
método ". Sin embargo, dado que se trata de un borrador, solo un control podría depender de la implementación. ¿Qué entorno utilizas?Respuestas:
La forma correcta de verificar la iterabilidad es la siguiente:
Por qué funciona esto (protocolo iterable en profundidad): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
Ya que estamos hablando de ... de, supongo que estamos en la mentalidad de ES6.
Además, no se sorprenda de que esta función devuelva
true
siobj
es una cadena, ya que las cadenas iteran sobre sus caracteres.fuente
Symbol.iterator in Object(obj)
,.return typeof obj[Symbol.iterator] === 'function'
? "Para ser iterable, un objeto debe implementar el método @@ iterator" - especifica el métodotypeof Object(obj)[Symbol.iterator] === 'function'
Funcionaría en todos los casos?¿Por qué tan prolijo?
fuente
Readability > Cleverness
siempre vuelvetrue
.Readability > Cleverness
, acortar la variableobject
ao
no ayuda a nadie. 2. Una cadena vacía''
es iterable y, por lo tanto, debe regresartrue
.!= null
La solución más simple es en realidad esta:
Object
envolverá todo lo que no sea un objeto en uno, lo que permitirá alin
operador trabajar incluso si el valor original no es un Objeto.null
yundefined
se convierten en objetos vacíos, por lo que no hay necesidad de detección de casos de borde, y las cadenas se envuelven en objetos String que son iterables.fuente
Symbol.iterator
.Object
es un desperdicio para este tipo de verificación.Object
se implementa la función, pero solo crea un nuevo objeto si aúnvalue
no es un objeto. Espero que la combinación dein
yObject(...)
sea algo que los motores de navegador puedan optimizar fácilmente, a diferencia de, por ejemplovalue !== undefined && value !== null && value[Symbol.iterator] && true
. Además, es extremadamente legible, lo que me importa.Como nota al margen, TENGA CUIDADO con la definición de iterable . Si viene de otros idiomas, esperaría que algo con lo que pueda iterar, por ejemplo, un
for
bucle sea iterable . Me temo que ese no es el caso aquí, donde iterable significa algo que implementa el protocolo de iteración .Para aclarar las cosas, todos los ejemplos anteriores devuelven
false
este objeto{a: 1, b: 2}
porque ese objeto no implementa el protocolo de iteración. Por lo tanto, no podrá iterar sobre él con unfor...of
PERO todavía puede hacerlo con unfor...in
.Entonces, si desea evitar errores dolorosos, haga que su código sea más específico cambiando el nombre de su método como se muestra a continuación:
fuente
undefined
?object !== null
en su respuesta, pero lo está haciendo,object != null
por lo que no está rompiendoundefined
en ese caso específico. He actualizado mi respuesta en consecuencia.hasIterationProtocol('')
debe regresartrue
! ¿Qué tal si elimina su código y simplemente deja la sección de explicación iterable, que es lo único que agrega valor real / algo nuevo en su respuesta?true
, al eliminar parte de la respuesta anterior fusioné ambas funciones y me olvidé de la comparación estricta. Ahora devolví la respuesta original que estaba funcionando bien.Object(...)
, buena captura. Pero en ese caso no se necesita la verificación nula.Hoy en día, como ya se dijo, para probar si
obj
es iterable simplemente hagaRespuesta histórica (no más válida)
los
for..of
constructo es parte del borrador de especificación de idioma de la 6ª edición de ECMASCript. Entonces podría cambiar antes de la versión final.En este borrador, los objetos iterables deben tener la función
iterator
como propiedad.Puede verificar si un objeto es iterable como este:
fuente
Para iteradores asíncronos , debe buscar el 'Symbol.asyncIterator' en lugar de 'Symbol.iterator':
fuente
Si quisiera comprobar de hecho si una variable es un objeto (
{key: value}
) o una matriz ([value, value]
), puede hacerlo:fuente