Escopo e closures no JavaScript
Posted: janeiro 30th, 2010 | Author: diegoquinteiro | Filed under: Uncategorized | Tags: javascript, orientação a objeto | 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.
Português
English
“Orientação à objeto” não tem crase.
Verdade, obrigado =D
Verdade, obrigado =D