Nos documentos MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
A for...of
construção é descrita para ser capaz de iterar sobre objetos "iteráveis". Mas existe uma boa maneira de decidir se um objeto é iterável?
Tentei encontrar propriedades comuns para arrays, iteradores e geradores, mas não consegui.
Além de fazer um for ... of
bloco try e verificar erros de tipo, existe uma maneira limpa de fazer isso?
javascript
simonzack
fonte
fonte
iterator()
método. ". No entanto, como este é um rascunho, apenas um cheque pode ser dependente da implementação. Qual ambiente você usa?Respostas:
A maneira adequada de verificar a iterabilidade é a seguinte:
Por que isso funciona (protocolo iterável em profundidade): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
Já que estamos falando sobre for..of, presumo, estamos na mentalidade ES6.
Além disso, não se surpreenda que esta função retorne
true
seobj
for uma string, pois as strings iteram sobre seus caracteres.fonte
Symbol.iterator in Object(obj)
,.return typeof obj[Symbol.iterator] === 'function'
? "Para ser iterável, um objeto deve implementar o método @@ iterador" - especifica o métodotypeof Object(obj)[Symbol.iterator] === 'function'
em todos os casos?Por que tão prolixo?
fonte
Readability > Cleverness
sempre retornatrue
.Readability > Cleverness
, encurtar a variávelobject
para nãoo
ajuda ninguém. 2. Uma string vazia''
é iterável e, portanto, deve retornartrue
.!= null
A solução mais simples é realmente esta:
Object
irá envolver qualquer coisa que não seja um objeto em um, permitindo que oin
operador trabalhe mesmo se o valor original não for um objeto.null
eundefined
são transformados em objetos vazios, portanto, não há necessidade de detecção de casos extremos, e as strings são envolvidas em objetos String que são iteráveis.fonte
Symbol.iterator
.Object
é um desperdício para este tipo de cheque.Object
função é implementada, mas ela só cria um novo objeto sevalue
ainda não for um objeto. Eu esperaria que a combinação dein
eObject(...)
fosse algo que os mecanismos de navegação podem otimizar facilmente, ao contrário de dizervalue !== undefined && value !== null && value[Symbol.iterator] && true
. Além disso, é extremamente legível, o que me interessa.Como nota lateral, CUIDADO com a definição de iterável . Se você estiver vindo de outras linguagens, poderá esperar que algo que possa iterar com, digamos, um
for
loop seja iterável . Infelizmente, esse não é o caso aqui, onde iterável significa algo que implementa o protocolo de iteração .Para tornar as coisas mais claras, todos os exemplos acima retornam
false
sobre esse objeto{a: 1, b: 2}
porque esse objeto não implementa o protocolo de iteração. Portanto, você não será capaz de iterar sobre ele com um,for...of
MAS ainda pode com umfor...in
.Portanto, se você deseja evitar erros dolorosos, torne seu código mais específico renomeando seu método conforme mostrado abaixo:
fonte
undefined
?object !== null
em sua resposta, mas você está fazendoobject != null
isso, não há rompimentoundefined
nesse caso específico. Eu atualizei minha resposta de acordo.hasIterationProtocol('')
deve retornartrue
! Que tal você remover seu código e apenas sair da seção de explicação iterável, que é a única coisa que agrega valor real / algo novo em sua resposta.true
, removendo parte da resposta antiga, eu mesclei as funções e esqueci a comparação estrita. Agora coloquei de volta a resposta original, que estava funcionando bem.Object(...)
, boa pegada. Mas, nesse caso, a verificação de nulo não é necessária.Hoje em dia, como já foi dito, para testar se
obj
é iterável basta fazerResposta histórica (não mais válida)
O
for..of
constructo é parte do ECMASCript 6ª edição do Language Specification Draft. Portanto, isso pode mudar antes da versão final.Neste rascunho, os objetos iteráveis devem ter a função
iterator
como uma propriedade.Você pode verificar se um objeto é iterável assim:
fonte
Para iteradores assíncronos, você deve verificar o 'Symbol.asyncIterator' em vez de 'Symbol.iterator':
fonte
Se você quiser verificar de fato se uma variável é um objeto (
{key: value}
) ou um array ([value, value]
), você pode fazer isso:fonte