let
e const
tem duas grandes diferenças entre var
:
- Eles têm escopo de bloco .
- Acessar um
var
antes de ser declarado tem o resultado undefined
; acessar um let
ou const
antes de ser declarado lança ReferenceError
:
console.log(aVar); // undefined
console.log(aLet); // causes ReferenceError: aLet is not defined
var aVar = 1;
let aLet = 2;
Parece a partir desses exemplos que as let
declarações (e const
, que funcionam da mesma maneira) não podem ser hasteadas , pois aLet
não parecem existir antes de receber um valor.
Isso não é o caso, no entanto- let
e const
são içadas (como var
, class
e function
), mas há um período entre uma entrada escopo e ser declarado onde eles não podem ser acessados. Este período é a zona morta temporal (TDZ) .
O TDZ termina quando aLet
é declarado , em vez de atribuído :
//console.log(aLet) // would throw ReferenceError
let aLet;
console.log(aLet); // undefined
aLet = 10;
console.log(aLet); // 10
Este exemplo mostra que let
é içado:
let x = 'outer value';
(function() {
// start TDZ for x
console.log(x);
let x = 'inner value'; // declaration ends TDZ for x
}());
Crédito: Zona morta temporal (TDZ) desmistificada
O acesso x
no escopo interno ainda causa a ReferenceError
. Se let
não fosse içado, seria registrado outer value
.
O TDZ é uma coisa boa porque ajuda a destacar erros - acessar um valor antes que ele seja declarado raramente é intencional.
O TDZ também se aplica a argumentos de função padrão. Os argumentos são avaliados da esquerda para a direita e cada argumento está no TDZ até que seja designado:
// b is in TDZ until its value is assigned
function testDefaults(a=b, b) { }
testDefaults(undefined, 1); // throws ReferenceError because the evaluation of a reads b before it has been evaluated.
O TDZ não está ativado por padrão no transpiler babel.js. Ative o modo "alta conformidade" para usá-lo no REPL . Forneça o es6.spec.blockScoping
sinalizador para usá-lo com a CLI ou como uma biblioteca.
Leitura adicional recomendada: TDZ desmistificado e ES6 Let, Const e a "Zona morta temporal" (TDZ) em profundidade .