# JavaScript IIFE como contêiner de códigos

> IIFE JavaScript: container de código isolado essencial. Entenda Immediately Invoked Function Expression para escopo protegido e encapsulamento. Domine!

URL: https://dpw.dev/javascript/javascript-iife-conteiner-de-codigos/  
Publicado em: 2014-06-09  
Categoria: javascript  
Tags: planejamento  
Autor: Tárcio Zemel

**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](/categoria/javascript/).

Mas, quando você decide continuar nos estudos e começa a inspecionar códigos alheios, inevitavelmente você se depara com algo como:

```javascript
(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.

> Artigo baseado em [What (function (window, document, undefined) {})(window, document); really means](http://toddmotto.com/what-function-window-document-undefined-iife-really-means/).

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:

```javascript
(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:

```javascript
(function (window, document, undefined) {
    var name = 'Foo';
})(window, document);

console.log(name); // "name" não definido, está em um escopo diferente

```

## Como funciona IIFE

Uma função normal se parece com isso:

```javascript
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:

```javascript
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):

```javascript
(function () {

})();

```

O par de parênteses extra é necessário. Isso não funciona:

```javascript
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:

```javascript
!function () {

}();

```

E existem variantes:

```javascript
+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:

```javascript
(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`:

```javascript
(function (window, document) {
    // é possível usar "window" e "document" normalmente
})(window, document);

```

A resolução de variáveis

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
