Escopo variável (JavaScript)

 

Publicado: agosto de 2016

A linguagem JavaScript tem dois escopos: global e local.  Uma variável declarada fora de uma definição de função é uma variável global, e seu valor será acessível e modificável em todo o seu programa.  Uma variável declarada dentro de uma definição de função é local.  Ela é criada e destruída sempre que a função é executada e não pode ser acessada por qualquer código fora da função.  O JavaScript não suporta escopo de bloco (no qual um conjunto de chaves {. . .} define um novo escopo), exceto em caso especial de variáveis com escopo em bloco.  

Uma variável local pode ter o mesmo nome que uma variável global, mas é totalmente separada. A alteração do valor de uma variável não afeta a outra.  Somente a versão local tem significado dentro da função na qual ela é declarada.  

// Global definition of aCentaur.
var aCentaur = "a horse with rider,";

// A local aCentaur variable is declared in this function.
function antiquities(){

   var aCentaur = "A centaur is probably a mounted Scythian warrior";
}

antiquities();
aCentaur += " as seen from a distance by a naive innocent.";

document.write(aCentaur);

// Output: "a horse with rider, as seen from a distance by a naive innocent."

No JavaScript, as variáveis são avaliadas como se fossem declaradas no início do escopo no qual existam.  Às vezes, isso resulta em comportamentos inesperados, como mostrado aqui.  

var aNumber = 100;
tweak();

function tweak(){

    // This prints "undefined", because aNumber is also defined locally below.
    document.write(aNumber);

    if (false)
    {
        var aNumber = 123;  
    }
}

Quando o JavaScript executa uma função, ele primeiro procura todas as declarações de variáveis, por exemplo, var someVariable;.  Ela cria as variáveis com um valor inicial de undefined.  Se a variável for declarada com um valor, por exemplo var someVariable = "something";, inicialmente ela ainda terá o valor undefined e assumirá o valor declarado somente quando a linha contendo a declaração for executada.  

O JavaScript processa todas as declarações de variáveis antes de executar qualquer código, independentemente de a declaração estar dentro ou não de um bloco condicional ou de qualquer outra construção.  Depois de encontrar todas as variáveis, o JavaScript executa o código na função.  Se uma variável estiver implicitamente declarada dentro de uma função, ou seja, se ela aparecer no lado esquerdo de uma expressão de atribuição, mas não tiver sido declarada com var, ela será criada como uma variável global.  

No JavaScript, uma função interna (aninhada) armazena referências a variáveis locais presentes no mesmo escopo que a função em si, mesmo após os retornos da função.  Este conjunto de referências é chamado um fechamento.  No exemplo a seguir, a segunda chamada para a função interna gera a mesma mensagem (“Hello Bill”) assim como a primeira chamada, porque o parâmetro de entrada para a função externa, name, é uma variável local que é armazenada no fechamento da função interna.  

function send(name) {
    // Local variable 'name' is stored in the closure
    // for the inner function.
    return function () {
        sendHi(name);
    }
}

function sendHi(msg) {
    console.log('Hello ' + msg);
}

var func = send('Bill');
func();
// Output:
// Hello Bill
sendHi('Pete');
// Output:
// Hello Pete
func();
// Output:
// Hello Bill

O Internet Explorer 11 apresenta suporte a let e const, que são variáveis com escopo no bloco.  Para essas variáveis, as chaves {. . .} definem um novo escopo.  Quando você define dessas variáveis para um valor específico, o valor só será aplicado ao escopo ao qual está definido.  

O exemplo a seguir ilustra o uso de let e do escopo de bloqueio.

System_CAPS_noteObservação

O código a seguir não é suportado no modo padrão do Internet Explorer 11 e posteriores.

let x = 10;
var y = 10;
{
    let x = 5;
    var y = 5;
    {
        let x = 2;
        var y = 2;
        document.write("x: " + x + "<br/>");
        document.write("y: " + y + "<br/>");
        // Output:
        // x: 2
        // y: 2
    }
    document.write("x: " + x + "<br/>");
    document.write("y: " + y + "<br/>");
    // Output:
    // x: 5
    // y: 2
}

document.write("x: " + x + "<br/>");
document.write("y: " + y + "<br/>");
// Output:
// x: 10
// y: 2
Mostrar: