A diferença está no escopo das variáveis declaradas com cada uma.
Na prática, há várias consequências úteis da diferença de escopo:
let
variáveis são visíveis apenas no bloco envolvente mais próximo ( { ... }
).
let
variáveis são utilizáveis apenas em linhas de código que ocorrem após a declaração da variável (mesmo que sejam içadas !).
let
variáveis não podem ser redeclaradas por um subseqüente var
ou let
.
let
Variáveis globais não são adicionadas ao window
objeto global .
let
As variáveis são fáceis de usar nos fechamentos (elas não causam condições de corrida ).
As restrições impostas let
reduzem a visibilidade das variáveis e aumentam a probabilidade de colisões inesperadas de nomes serem encontradas com antecedência. Isso facilita o rastreamento e o raciocínio sobre as variáveis, incluindo sua acessibilidade (ajudando na recuperação de memória não utilizada).
Consequentemente, let
é menos provável que as variáveis causem problemas quando usadas em programas grandes ou quando estruturas desenvolvidas independentemente são combinadas de maneiras novas e inesperadas.
var
ainda pode ser útil se você tiver certeza de que deseja o efeito de ligação única ao usar um fechamento em um loop (nº 5) ou para declarar variáveis globais visíveis externamente em seu código (nº 4). O uso de var
para exportações pode ser substituído se export
migrar do espaço do transpiler para o idioma principal.
Exemplos
1. Não usar fora do bloco anexo mais próximo:
Este bloco de código gerará um erro de referência porque o segundo uso de x
ocorre fora do bloco em que é declarado com let
:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
Por outro lado, o mesmo exemplo com var
obras.
2. Sem uso antes da declaração:
Este bloco de código lançará um ReferenceError
antes que o código possa ser executado porque x
é usado antes de ser declarado:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
Por outro lado, o mesmo exemplo var
analisa e é executado sem gerar nenhuma exceção.
3. Sem redeclaração:
O código a seguir demonstra que uma variável declarada com let
não pode ser redeclarada posteriormente:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
4. Globais não ligados a window
:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
5. Fácil utilização com fechamentos:
Variáveis declaradas com var
não funcionam bem com fechamentos dentro de loops. Aqui está um loop simples que gera a sequência de valores que a variável i
possui em diferentes pontos no tempo:
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
Especificamente, isso gera:
i is 0
i is 1
i is 2
i is 3
i is 4
No JavaScript, geralmente usamos variáveis em um período significativamente posterior ao quando elas são criadas. Quando demonstramos isso, adiando a saída com um fechamento passado para setTimeout
:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... a saída permanece inalterada enquanto permanecermos let
. Por outro lado, se tivéssemos usado var i
:
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... o loop gera inesperadamente "i is 5" cinco vezes:
i is 5
i is 5
i is 5
i is 5
i is 5
let
está incluído no rascunho da 6ª edição e provavelmente estará na especificação final.