var nome = 'Pablo Escobar';
function dizerNome() {
return alert(nome);
}
console.log(nome);
O contexto global é a janela do navegador, acessível pelo objeto window
(no browser) e global
no Node.
function figuraOculta() {
var oculta = 'cachorro';
return alert('Existe uma figura oculta, que é um ' + oculta + ' atras.');
}
alert(oculta); // erro
Ao contrário do escopo global, as variáveis dentro de uma função pertencem a função que engloba estas variáveis.
Vale lembrar que em JavaScript, declarações sem var resultam na variável sendo jogada para o escopo global.
function variableHoisting() {
alert(nome);
var nome = 'foo';
}
variableHoisting(); // o que acontece?
function variableHoisting() {
alert(nome);
var nome = 'foo';
}
variableHoisting(); // não resulta em erro!
function variableHoisting() {
var nome; // declaração movida para início do escopo
alert(nome);
nome = 'foo';
}
variableHoisting(); // alerta undefined
function digaNome(nome) {
function capitalizar() {
return nome[0].toUpperCase() + nome.substr(1).toLowerCase();
}
return alert(capitalizar());
}
digaNome("RoBeRTO"); // alerta "Roberto".
capitalizar() // erro!
As regras são as mesmas.
function digaNome(nome) {
function capitalizar() {
return nome[0].toUpperCase() + nome.substr(1).toLowerCase();
}
return alert(capitalizar());
}
Mesmo que eu não tenha declarado a variável nome dentro da função capitalizar, consigo usar este valor dentro da função "de dentro".
Uma função "se lembra" de variáveis definidas no contexto no qual ela própria é definida.
Este é o conceito de closures.
(function() {
var a = 0;
console.log(a); // escreve "0" no console
// a variável "a" só existe neste escopo.
// Logo, deixará de existir assim que esta função acabar
})();
console.log(a); // erro
Note como é possível criar uma função e executá-la envolvendo-a em parênteses e chamando-a.
function soma(a) {
return function (b) {
return a + b;
}
}
var soma5 = soma(5);
var resultado = soma5(3);
alert(resultado); // alerta "8"
function Walker(seed) {
var init = seed || 0;
return {
next: function() {
return ++init;
},
cur: function() {
return init;
},
back: function() {
return --init;
}
};
}
var first = Walker(5);
console.log(first.next()); // 6
console.log(first.next()); // 7
console.log(first.next()); // 8
var second = Walker();
console.log(second.next()); // 1
console.log(second.cur()); // 1
console.log(second.back()); // 0
// first.seed -> erro!
// second.seed -> erro!
Twitter: @panuto_
Github: @nubunto
Nodeschool Campinas 2015