JavaScript IIFE como contêiner de códigos
JavaScript puro ou Vanilla JavaScript (felizmente) está voltando. E com força. Aqui, mesmo, no desenvolvimento para web, você consegue encontrar vários artigos mostrando como é possível fazer tudo o que você faz com bibliotecas de centenas de KB com poucas linhas de código.
Mas, quando você decide continuar nos estudos e começa a inspecionar códigos alheios, inevitavelmente você se depara com algo como:
(function (window, document, undefined) { //})(window, document);E você encontra isso em diversos códigos; e vê outros desenvolvedores indicando; e colegas dizendo que esta é uma boa prática. Mas você sabe o que, realmente, isso significa? Continue lendo.
Frequentemente desenvolvedores descobrindo (ou redescobrindo) o JavaScript puro se perguntam sobre IIFE (Expressão de Função Imediatamente Invocada ou Immediately-Invoked Function Expression), frequentemente apresentado da seguinte maneira:
(function (window, document, undefined) { //})(window, document);Na verdade, várias coisas estão acontecendo aí. Analisemos cada uma delas.
Escopo privado em IIFE
JavaScript tem maneiras interessantes de trabalhar com escopo de função; então, primeiramente essa expressão cria um “âmbito privado” (private scope). Por exemplo:
(function (window, document, undefined) { var name = 'Foo';})(window, document);
console.log(name); // "name" não definido, está em um escopo diferenteComo funciona IIFE
Uma função normal se parece com isso:
var logMyName = function (name) { console.log(name);};
logMyName('Foo');Ela é chamada (invoke) quando necessário, por escolha do programador, em qualquer ponto do código em que se queira e/ou seja possível.
A razão pela qual essa IIFE em JavaScript foi criada, foi para ser uma expressão de função imediatamente invocada, o que significa que elas são imediatamente chamadas em tempo de execução - também, não é possível chamá-la novamente, já que elas só rodam uma vez, mais ou menos assim:
var logMyName = (function (name) { console.log(name); // Todd})('Todd');O pulo-do-gato aqui é isso (que já foi atribuído a uma variável no exemplo anterior):
(function () {
})();O par de parênteses extra é necessário. Isso não funciona:
function () {
}();Embora existam vários truques que podem ser feitos para “enganar” o JavaScript e fazê-lo funcionar. Este, por exemplo, força o parser de JavaScript a tratar o código que segue ! como uma expressão:
!function () {
}();E existem variantes:
+function () {
}();
-function () {
}();
~function () {
}();Mas não é preciso se forçar a decorar isso para usar a todo momento para fazer uma IIFE.
Argumentos da IIFE
Agora que foi explicado como isso funciona, passemos para os argumento da IIFE:
(function (window) {
})(window);Como isso funciona? Lembre-se, (window); é onde a função é chamada, e onde é passado o Objeto window. Então ele é passado para a função - que também foi chamada de window.
Então, o que mais é possível fazer? Passar tudo o que for necessário! Por exemplo, passar o Objeto document:
(function (window, document) { // é possível usar "window" e "document" normalmente})(window, document);A resolução de variáveis