En los documentos de MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
La for...ofconstrucció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 ... ofbloque 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
truesiobjes 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 > Clevernesssiempre vuelvetrue.Readability > Cleverness, acortar la variableobjectaono ayuda a nadie. 2. Una cadena vacía''es iterable y, por lo tanto, debe regresartrue.!= nullLa solución más simple es en realidad esta:
Objectenvolverá todo lo que no sea un objeto en uno, lo que permitirá alinoperador trabajar incluso si el valor original no es un Objeto.nullyundefinedse 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.Objectes un desperdicio para este tipo de verificación.Objectse implementa la función, pero solo crea un nuevo objeto si aúnvalueno es un objeto. Espero que la combinación deinyObject(...)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
forbucle 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
falseeste 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...ofPERO 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 !== nullen su respuesta, pero lo está haciendo,object != nullpor lo que no está rompiendoundefineden 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
objes iterable simplemente hagaRespuesta histórica (no más válida)
los
for..ofconstructo 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
iteratorcomo 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