Mecanismo de Iteração no JS, e talvez um possível bug?
Tags: javascript, discuss
Published: 2019-10-26 14:43:02

Olá pessoa! Hoje levantarei uma discussão a respeito do conceito de **iteração**, um mecanismo que foi incluído no ES6 extremamente poderoso. Lá estava eu aprendendo esse conceito quando me deparei com um questionamento! Mas antes irei da uma breve introdução desse mecanismo.

Tradicionalmente antes do advento dos métodos auxiliares de iteração como os de Array, sempre usamos as estruturas de repetição como for.. e while.. para realizar tarefas triviais no dia a dia de um desenvolvedor.

Agora com o advento desse mecanismo no JS, temos a possibilidade de poder percorrer as estruturas de dados iteráveis sem a necessidade de ter que nos preocuparmos em como iremos itera-las. Mas sem delongas, vamos ao código!

Uma coisa que precisamos entender antes de botar a mão no código é que o conceito de iteração é definido por outros dois sub-conceitos: **iteráveis** e **iteradores**. Basicamente podemos entender os iteráveis como sendo as estruturas de dados como: Array, Maps, Sets e Strings que são objetos nativos iteráveis por padrão no JS, e os iteradores sendo o objetos que sabem como percorrer esses iteráveis. Portanto você pode resumir que para cada estrutura iterável existe um iterador associado que sabe como acessar seus items. Sabendo disso agora é só decolarmos o foguete.

Vamos aos exemplos, lobo abaixo podemos definir um iterável do tipo Array.

```js
const bruxos = ['Harry Poter', 'Hermione Granger', 'Rony weasley']
```
Agora para obtemos o seu iterador, passamos a propriedade "Symbol.iterador" entre colchetes, em seguida armazenamos seu iterador que é um objeto na constante iterador.
```js
const bruxos = ['Harry Poter', 'Hermione Granger', 'Rony weasley']
const iterador = bruxos[Symbol.iterador]()
```
Agora podemos percorrer um a um os items do iterável Array. Outro detalhe é que podemos usar um método do objeto iterador que obtemos chamado next() usado para acessar os items do iterável sempre que é chamado.

```js
const bruxos = ['Harry Poter', 'Hermione Granger', 'Rony weasley']
const iterador = bruxos[Symbol.iterador]()

iterador.next() // retorna { value: 'Harry Poter', done: false }
iterador.next() // retorna { value: 'Hermione Granger', done: false }
iterador.next() // retorna { value: 'Rony weasley', done: false }
iterador.next() // retorna { value: undefined, done: true }

```
Perceba que para cada chamada do next() temos o retorno de um objeto com duas propriedades, value que guarda o valor do índice do Array e done que armazena um boleano que indica se toda a estrutura já foi acessada. Note que na ultima chamada o done do objeto retornado armazena um true indicando que a estrutura já foi toda acessada.

Bom, essa foi uma introdução rápida sobre o mecanismo, mais para você que ainda não conhecia ficar por dentro da novidade. Recomendo fortemente da uma olhada na documentação [protocolos de iteração](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) na MDN pra expandir seu conhecimento.

Tendo contextualizado um pouco o assunto, vamos voltar naquela minha duvida que mencionei logo inicio.

Perceba que nas ultimas duas linhas descritas a seguir:

```js
iterador.next() // retorna { value: 'Rony weasley', done: false }
iterador.next() // retorna { value: undefined, done: true }
```
O que não ficou muito claro, pelo menos na minha percepção, foi a necessidade de termos que chama o next() para obtemos no objeto retornado em sua propriedade done um true indicando que a iteração se encerrou ali, sendo que na verdade ela se encerra na chamada anterior, o que faria mais sentido. Bom, deixo aqui essa discussão para podemos chegar em uma conclusão juntos. Valeu Devs!