Pegadinha #1 de entrevistas em JavaScript

Escrito por

Hoje quero comentar uma questão muito comum em entrevistas de JavaScript.

Qual é a saída desse código?

1const arr = ["a", "b", "c", "d"]
2for (var i = 0; i < arr.length; i++) {
3 setTimeOut(() => {
4 console.log(i, arr[i])
5 }, 0)
6}
7console.log("out", i)

Detalhe que estamos utilizando um setTimeOut com um zero, mas poderia ser qualquer valor.

O primeiro detalhe é que percebemos que o out saiu primeiro com o número 4. O ‘var’ foi definido dentro do for, porém eu consegui dar um console log lá é baixo. Podemos chegar a conclusão que ele não respeitou o escopo. Outro ponto importante é que ele aconteceu antes do restante, isso acontece porque sempre que utilizamos o setTimeOut, ele leva essa execução da arrow function para dentro do event loop.

Como o i já está com 4, ele não é um número válido, pois nosso array inicia-se em zero e termina em 3. Por esse motivo virá o seguinte:

1out 4
2
34 undefined
44 undefined
54 undefined
64 undefined

Como arrumamos essa função?

Temos algumas formas de arrumar isso. Existe uma bem simples e algumas que podemos brincar um pouco mais.

A primeira bem simples é trocar o var por let:

1for (let i=0; i<arr.length; i++){
2 setTimeOut(() => {
3 console.log(i, arr[i])
4 },0)

Agora funcionou perfeitamente:

10 'a'
21 'b'
32 'c'
43 'd'

Por que essa diferença?

Quando estamos com o var, seria equivalente a quando ele estiver executando o código ele puxa todos os vars pra cima, isso é conhecido como hoisting.

Por esse motivo, sempre que possível, utilize let e const.

Outra maneira seria transformar em setTimeOut em uma maneira que eu consiga injetar as variáveis dentro dele mesmo, como uma self invoked:

1setTimeOut(
2 (function(ii) {
3 return () => {
4 console.log(ii, arr[ii])
5 }
6 })(i),
7 0
8)

Iremos executar a função e a partir da function o ii vai estar válido. Assim funcionará também do jeito que esperávamos.

Confira o video:

Deixe suas dúvidas e sugestões nos comentários. Curta o DevPleno no Facebook, se inscreva no canal no YouTube e cadastre seu e-mail para não perder as atualizações. Abraço!

Evolua mais rápido

Junte-se a milhares de desenvolvedores no nosso time de alunos premium e alcance mais rápido o próximo nível da sua carreira.

Ver cursos Premium