Diferença entre usar nulo vs quebra automática de parênteses para a função nula IIFE () vs (function ())
A prática comum para criar módulos é envolvê-los em parênteses, para que você não vaze nenhuma variável fora do módulo (ao concatenar etc).
Há tambémvoid
operador, que avalia uma determinada expressão e retornaundefined
. (Veja emMDN)
Gostaria de saber qual é a razão por trás de preferir funções de quebra de parênteses em vez de usarvoid
. É histórico, algo relacionado à concatenação?
Sei que você pode ter problemas com a concatenação quando um dos arquivos tem um ponto-e-vírgula ausente, causando problemas desagradáveis até você perceber.
ExemplosDigamos, module1.js (observe a vírgula ausente):
(function () {
return function () {
console.log('module1. I should not be called');
};
})()
e module2.js:
(function () {
return function () {
console.log('module2. I should not be called either');
};
})();
Se você concatenar esses scripts em um pacote, ele produzirá o seguinte:
(function () {
return function () {
console.log('module1. I should not be called');
};
})()(function () {
return function () {
console.log('module2. I should not be called either');
};
})();
Como os dois módulos (arquivos) retornam uma função, o segundo supostamente IIFE se torna uma invocação dovalor de retorno do primeiro módulo, chamando efetivamenteconsole.log
. A solução comum para isso é declarar seu módulo com!(function (){})();
o que força o valor retornado a ser um booleano.
Se, no entanto, você deveria usarvoid
, gostar:
void function () {
return function () {
console.log('module1. I should not be called');
};
}()
O arquivo concatenado ainda estará errado, mas você notará o erro na primeira execução, portanto, mais facilmente percebido. Ver abaixo.
void function () {
return function () {
console.log('module1. I should not be called');
};
}()void function () {
return function () {
console.log('module2. I should not be called either');
};
});
Isso jogaUnexpected token void
. No que diz respeito aos módulos, acredito!(function(){}()
evoid function(){}()
alcançar o mesmo efeito. Mas eu sinto quevoid
parece mais limpo (subjetivo) do que agrupar uma função com parâmetros e anexar!
para isso.
Estou faltando alguma coisa? Não seria melhor se usássemosvoid
?