Expressões de Função Imediatamente Invocadas – IIFE

Mesmo se você for um programador novo, não irá demorar muito quando você trabalhar com JavaScript antes de se deparar com esse padrão:

(function () {
    // código
})();

Ao primeiro encontro provavelmente parecerá bastante confuso, no entanto, o conceito em si é simples.

O padrão é chamado de expressão de função imediatamente invocada (Inglês: Immediate Invoking Function Expression) ou IIFE (pronunciado “iffy”).

Em JavaScript funções podem ser criadas através de uma declaração de função ou uma expressão de função. Uma declaração de função é a maneira “normal” de criar uma função nomeada.

function myFunction () { 
    /* código */ 
}

Por outro lado, se você está atribuindo uma função a uma variável ou propriedade, você está lidando com uma expressão de função.

var umaFunc= function () { /* código */ };

var objeto = {
    myFunction: function () { /* código */ }
};

Uma função criada no contexto de uma expressão também é uma expressão de função. Por exemplo:

(function () { /* código */ });

A principal coisa sobre expressões JavaScript é que elas retornam valores. Em ambos os casos, acima do valor de retorno da expressão é a função.

Isso significa que, se quisermos invocar a expressão de função imediatamente, precisamos apenas colocar alguns parênteses no final. O que nos traz de volta ao primeiro trecho de código que vimos.

(function () {
    // código
})();

Agora sabemos o que o código está fazendo, mas a pergunta “Por quê?” ainda resta.

A principal razão para usar um IIFE é obter privacidade de dados. Como var variáveis do escopo do JavaScript para sua função de contenção, quaisquer variáveis declaradas no IIFE não podem ser acessadas pelo mundo externo.

(function () {
    var foo = "bar";

    // exibe: "bar"
    console.log(foo);
})();

// Se tentar acessar a variavel, ocorrerá um erro
// ReferenceError: foo is not defined
console.log(foo);

É claro que, você poderia explicitamente nomear e depois invocar uma função para alcançar os mesmos fins.

function myImmediateFunction () {
    var foo = "bar";

    // exibe: "bar"
    console.log(foo);
}

myImmediateFunction();

// Igual ao exemplo anterior, se tentar acessar a variavel, ocorrerá um erro 
// ReferenceError: foo is not defined
console.log(foo);

No entanto, esta abordagem tem algumas desvantagens. Primeiro, ele ocupa desnecessariamente um nome no namespace global, aumentando a possibilidade de colisões de nomes. Em segundo lugar, as intenções deste código não são tão auto-documentadas quanto um IIFE. E terceiro, porque é nomeado e não é auto-documentado, pode acidentalmente ser invocado mais de uma vez.

Vale a pena ressaltar que você também pode facilmente passar argumentos para o IIFE.

var foo = "foo";

(function (innerFoo) {
    // exibe: "foo"
    console.log(innerFoo);
})(foo);

E essa é a história por trás dos IIFEs. Em breve, estaremos desenvolvendo isso analisando o padrão de módulo em JavaScript.

Tradução:

http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html