Você sabia?
Em JavaScript as funções filhas sempre tem acesso às variáveis da função pai. More...

Escopo e closures no JavaScript

Posted: janeiro 30th, 2010 | Author: diegoquinteiro | Filed under: Uncategorized | Tags: , | 3 Comments »


Conheça o escopo das suas variáveis. Em JavaScript só funções definem escopos e só variáveis declaradas explicitamente usando var ficam restritas ao escopo, as demais são globais. Adicionalmente, todos os parâmetros de uma função são variáveis locais. Preste atenção no seguinte exemplo:

function exemplo (arg) {
	var variavelLocal = 0;
	if (arg > 0) {
		var mesmoEscopo = arg + 1;
	}
	variavelLocal = mesmoEscopo;
	alert(variavelLocal);
	variavelGlobal = arg;
}

exemplo(1); // Alerta "2"

alert(variavelLocal); // Alerta "undefined"

alert(mesmoEscopo); // Alerta "undefined"

alert(variavelGlobal); // Alerta "1"

Note que a variável mesmoEscopo pode ser atribuída à variavelLocal fora do bloco if em que foi definida. O bloco não define um escopo, apenas a função.

O JavaScript sempre define um objeto global, que nos navegadores é o objeto window. Todas as variáveis globais são na verdade propriedades desse objeto, de forma que:

exemplo(0);

window.exemplo(1); // funções também são variáveis

alert(variavelGlobal); // Alerta "1"

alert(window.variavelGlobal); // Alerta "1" também

alert(variavelGlobal === window.variavelGlobal); // Alerta "true"

Closures

Funções em JavaScript são objetos de primeira classe. Isso significa que você pode passar uma função por parâmetro, atribuir uma função a uma variável e até usar uma função como retorno de outra função. A declaração function nomeDaFuncao(arg1, arg2, …) { … corpo … } tem exatamente o mesmo efeito que var nomeDaFuncao = function (arg1, arg2, …) { … corpo … };.

As funções declaradas dentro de outra função sempre tem acesso às variáveis da função pai. Por exemplo:

var funcaoPai = function (valor) {
    var variavelDaFuncaoPai = valor;
    var funcaoFilha = function () {
        alert(variavelDaFuncaoPai);
    }
    funcaoFilha();
}

funcaoPai(1); // Alerta "1";

Algo curioso acontece quando guardamos uma referência pra função filha depois do fim da execução da função pai. Veja:

var funcaoPai = function (valor) {
    var variavelDaFuncaoPai = valor;
    var funcaoFilha = function () {
        alert(variavelDaFuncaoPai);
    }
    return funcaoFilha;
}

var filha1 = funcaoPai(1);
var filha2 = funcaoPai(2);

filha1(); // Alerta "1"!
filha2(); // Alerta "2"!

Fazendo isso criamos um fechamento ou closure.

As variáveis locais criadas na execução de funcaoPai não foram destruídas ao fim de sua execução. A referência pra função filha foi retornada e guardada, e ela sempre terá acesso à variavelDaFuncaoPai e a valor, ambas variáveis locais de funcaoPai.

Esse recurso é muito poderoso e deve ser explorado, como veremos nos próximos posts.


3 Comments on “Escopo e closures no JavaScript”

  1. 1 Thársis said at 17:55 on abril 27th, 2010:

    “Orientação à objeto” não tem crase.

  2. 2 diegoquinteiro said at 21:14 on abril 27th, 2010:

    Verdade, obrigado =D

  3. 3 Emily said at 18:50 on junho 2nd, 2010:

    Verdade, obrigado =D


Leave a Reply