JavaScript pode parecer sintaticamente parecido com linguagens c-like, mas seu comportamento com relação ao escopo das variáveis funciona bem diferente do que estamos acostumados.

Nesse post vou tentar explicar como o utiliza seu escopo.

O javascript trabalha com o conceito de contexto de execução, chamando normalmente de contexto. O contexto define o escopo das variáveis ou funções.

O contexto mais externo é conhecido como contexto global (global context) e é representado por um objeto. Ele é diferente para cada ambiente de execução do javascript. O global context de um browser é o objeto window, para o node.js ele é acessível através do GLOBAL ou GLOBAL.window ( forma mais parecida com a dos browser). Toda variável ou função global é então um atributo desse objeto. Quando um contexto é finalizado ele remove todos os objetos que pertencem a ele.

Cada função tem seu próprio contexto de execução. Quando uma função é chamada seu contexto é incluído na pilha de execução, e removido quando a função termina sua execução retornando ao contexto anterior ao da função.

Pesquisa do indentificador

A cada execução de um contexto é criado uma “encadeamento de contexto” dos objetos na memória para permitir o acesso a todas as variáveis e funções que o contexto tem acesso. As declarações de funções e variáveis do contexto atual são os primeiros objetos que fazem parte dessa cadeia, os contextos encadeados começam dos mais próximos para os mais distantes na pilha de contextos.
A pesquisa pelo identificado percorre essa cadeia de contexto. A procura sempre ocorre do início da cadeia para o final até ele ser encontrado ou chegar ao ultimo contexto(global context).

Trabalhando com with e try catch.

O uso dessas expressões criam uma camada a mais no encadeamento de contexto. Com o with é criado uma camada de objetos com todos os atributos do objeto que está se trabalhando, e quando o catch é executado um objeto é incluído dando acesso a exceção jogada.

function() { with(location) { var url = href + ?run=1; } return url; }

Blocos sem escopo

Essa é com certeza a maior diferença entre javascript e as outras linguagens. No javascript blocos de código não criam um contexto próprio de execução permanecendo no contexto em que o o bloco foi executado.

if(true) { var nome = gabriel; } alert(nome); // gabriel

ou ainda mais confuso

for(i= 0;i<10;i++) { /*codigo */ } alert(i); // 10

Os programadores também tem que tomar cuidado quanto a declaração de variáveis. Se esquecer de utilizar o var a variável é incluída no contexto global e não no contexto de execução atual.

function f() { var a = 10; b = 20; return a + b; }
alert(f()); //30
alert(b); //20
alert(typeof a); //undefined

Referências:
javascript – node.js global variables? – Stack Overflow
Professional Javascript for web developer