Armadilhas das IIFE em JavaScript

Vamos examinar dois trechos de código.

Primeiro:

javascriptlet result = 1
+function() {
  return 2;
}();

console.log(result);

Segundo:

javascriptlet result = 1;
+function() {
  return 2;
}();

console.log(result);

Esses dois trechos de código são praticamente idênticos, mas se executados - o resultado será diferente. O primeiro código exibirá no console o número 3, enquanto o segundo - o número 1.

Por que essa diferença: tudo se deve ao fato de que em um caso, no final da primeira linha de código, falta o ponto e vírgula, e no segundo caso - está presente.

Você pode perguntar: como assim, mas em JavaScript o ponto e vírgula no final de um comando não é obrigatório! Na verdade, isso não é bem assim. Vamos entender o que realmente está acontecendo.

O primeiro código pode ser reescrito assim:

javascriptlet result = 1 + function() {
  return 2;
}();

console.log(result); // exibirá 3

Agora fica imediatamente óbvio que à unidade é somado o resultado da chamada da função imediata, ou seja, 2. Portanto, o resultado final será 3.

Se, por outro lado, colocarmos um ponto e vírgula após o 1, o código será interpretado de outra forma:

javascript// Primeiro comando:
let result = 1;

// Segundo comando:
+function() {
  return 2;
}();

// Terceiro comando:
console.log(result); // exibirá 1

Ou seja, a atribuição à variável e a chamada da função imediata se tornam comandos diferentes. E tudo por causa da presença do ponto e vírgula!

Assim, neste caso, a chamada da função imediata basicamente não faz nada - simplesmente retorna o número 2 para lugar nenhum, e que não afeta a variável result de forma alguma.

Vamos então entender, por que podemos não escrever o ponto e vírgula em JavaScript. Suponha que temos um código assim, sem pontos e vírgulas:

javascriptlet result = 1 // em result será armazenado 1
let test = 2   // em test será armazenado 2

Ele funciona corretamente, pois o interpretador inseriu automaticamente um ponto e vírgula no final de cada linha.

Mas veja este código:

javascriptlet result = 1
+ 2; // em result será armazenado 3

Agora, o ponto e vírgula no final da primeira linha não será inserido automaticamente, pois o interpretador compreende que o comando da segunda linha é parte do comando da primeira linha.

Mas se nós mesmos colocarmos o ponto e vírgula - o resultado será completamente diferente:

javascriptlet result = 1; // em result será armazenado 1
+ 2; // o comando não faz nada, mas também não haverá erro

Ou seja, o interpretador só insere o ponto e vírgula automaticamente se o próximo comando não for uma continuação do anterior.

E agora veja este código:

javascriptlet result = 1
+function() {
  return 2;
}();

console.log(result);

De fato, a segunda linha é simplesmente a continuação do comando da primeira linha e o interpretador não insere o ponto e vírgula automaticamente. É por isso que, se nós mesmos escrevermos o ponto e vírgula no final da primeira linha - o resultado será completamente diferente. Isso nos diz que é melhor sempre colocar o ponto e vírgula nos lugares certos, para evitar problemas.