JavaScript let: Declarando Variáveis ​​com Escopo de Bloco

Resumo : neste tutorial, você aprenderá como usar a letpalavra-chave JavaScript para declarar variáveis ​​com escopo de bloco.

Introdução à palavra-chave JavaScript let

No ES5, quando você declara uma variável usando a varpalavra-chave, o escopo da variável é global ou local. Se você declarar uma variável fora de uma função, o escopo da variável será global. Quando você declara uma variável dentro de uma função, o escopo da variável é local.

ES6 fornece uma nova maneira de declarar uma variável usando a letpalavra-chave. A letpalavra-chave é semelhante à varpalavra-chave, exceto que essas variáveis ​​têm escopo bloqueado. Por exemplo:

let variable_name;Linguagem de código:  JavaScript  ( javascript )

Em JavaScript, os blocos são indicados por chaves {}, por exemplo, if elsefor, do while, whilee try catchassim por diante:

if(condition) {
   // inside a block
}Linguagem de código:  JavaScript  ( javascript )

Veja o exemplo a seguir:

let x = 10;
if (x == 10) {
    let x = 20;
    console.log(x); // 20:  reference x inside the block
}
console.log(x); // 10: reference at the begining of the scriptLinguagem de código:  JavaScript  ( javascript )

Como funciona o roteiro:

  • Primeiro, declare uma variável xe inicialize seu valor como 10.
  • Segundo, declare uma nova variável com o mesmo nome xdentro do ifbloco, mas com valor inicial de 20.
  • Terceiro, imprima o valor da variável xdentro e depois do   ifbloco.

Como a letpalavra-chave declara uma variável com escopo de bloco, a xvariável dentro do ifbloco é uma nova variável e obscurece a xvariável declarada na parte superior do script. Portanto, o valor de xno console é 20.

Quando o mecanismo JavaScript conclui a execução do ifbloco, a xvariável dentro do ifbloco fica fora do escopo. Portanto, o valor da  xvariável que segue o if bloco é 10.

JavaScript let e objeto global

Ao declarar uma variável global usando a varpalavra-chave, você adiciona essa variável à lista de propriedades do objeto global . No caso do navegador web, o objeto global é o arquivo window. Por exemplo:

var a = 10;
console.log(window.a); // 10Linguagem de código:  JavaScript  ( javascript )

Entretanto, quando você usa a letpalavra-chave para declarar uma variável, essa variável não é anexada ao objeto global como uma propriedade. Por exemplo:

let b = 20;
console.log(window.b); // undefinedLinguagem de código:  JavaScript  ( javascript )

JavaScript let e função de retorno de chamada em um loop for

Veja o exemplo a seguir.

for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, 1000);
}Linguagem de código:  JavaScript  ( javascript )

A intenção do código é enviar números de 0 a 4 para o console a cada segundo. No entanto, ele gera o número 5cinco vezes:

5
5
5
5
5

Neste exemplo, a variável ié uma variável global. Após o loop, seu valor é 5. Quando as funções de callback são passadas para a setTimeout()execução da função, elas referenciam a mesma variável icom o valor 5.

No ES5, você pode corrigir esse problema criando outro escopo para que cada função de retorno de chamada faça referência a uma nova variável. E para criar um novo escopo, você precisa criar uma função. Normalmente, você usa o padrão IIFE da seguinte maneira:

for (var i = 0; i < 5; i++) {
    (function (j) {
        setTimeout(function () {
            console.log(j);
        }, 1000);
    })(i);
}Linguagem de código:  JavaScript  ( javascript )

Saída:

0
1
2
3
4

No ES6, a letpalavra-chave declara uma nova variável em cada iteração do loop. Portanto, você só precisa substituir a varpalavra-chave pela letpalavra-chave para corrigir o problema:

for (let i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, 1000);
}Linguagem de código:  JavaScript  ( javascript )

Para deixar o código completamente no estilo ES6, você pode usar uma função de seta como segue:

for (let i = 0; i < 5; i++) {
    setTimeout(() => console.log(i), 1000);
}Linguagem de código:  JavaScript  ( javascript )

Observe que você aprenderá mais sobre as funções de seta no tutorial posterior .

Redeclaração

A varpalavra-chave permite redeclarar uma variável sem nenhum problema:

var counter = 0;
var counter;
console.log(counter); // 0Linguagem de código:  JavaScript  ( javascript )

Entretanto, redeclarar uma variável usando a letpalavra-chave resultará em um erro:

let counter = 0;
let counter;
console.log(counter);Linguagem de código:  JavaScript  ( javascript )

Aqui está a mensagem de erro:

Uncaught SyntaxError: Identifier 'counter' has already been declaredLinguagem de código:  JavaScript  ( javascript )

JavaScript permite variáveis ​​e içamento

Vamos examinar o seguinte exemplo:

{
    console.log(counter); // 
    let counter = 10;    
}Linguagem de código:  JavaScript  ( javascript )

Este código causa um erro:

Uncaught ReferenceError: Cannot access 'counter' before initializationLinguagem de código:  JavaScript  ( javascript )

Neste exemplo, acessar a countervariável antes de declará-la causa um ReferenceError. Você pode pensar que uma declaração de variável usando a letpalavra-chave não eleva, mas eleva .

Na verdade, o mecanismo JavaScript irá elevar uma variável declarada pela letpalavra-chave para o topo do bloco. No entanto, o mecanismo JavaScript não inicializa a variável. Portanto, ao fazer referência a uma variável não inicializada, você obterá um arquivo ReferenceError.

Zona de morte temporal (TDZ)

Uma variável declarada pela letpalavra-chave possui a chamada zona morta temporal (TDZ). O TDZ é o tempo desde o início do bloco até o processamento da declaração da variável.

O exemplo a seguir ilustra que a zona morta temporal é baseada no tempo e não na localização .

{ // enter new scope, TDZ starts
    let log = function () {
        console.log(message); // messagedeclared later
    };

    // This is the TDZ and accessing log
    // would cause a ReferenceError

    let message= 'Hello'; // TDZ ends
    log(); // called outside TDZ
}Linguagem de código:  JavaScript  ( javascript )

Neste exemplo:

Primeiro, a chave inicia um novo escopo de bloco, portanto, o TDZ é iniciado.

Segundo, a log()expressão da função acessa a messagevariável. No entanto, a log()função ainda não foi executada.

Terceiro, declare a messagevariável e inicialize seu valor como 'Hello'. O tempo desde o início do escopo do bloco até o momento em que a messagevariável é acessada é chamado de zona de morte temporal . Quando o mecanismo JavaScript processa a declaração, o TDZ termina.

Por fim, chame a log()função que acessa a messagevariável fora do TDZ.

Observe que se você acessar uma variável declarada pela letpalavra-chave na TDZ, obterá a ReferenceErrorconforme ilustrado no exemplo a seguir.

{ // TDZ starts
    console.log(typeof myVar); // undefined
    console.log(typeof message); // ReferenceError
    let message; // TDZ ends
}Linguagem de código:  JavaScript  ( javascript )

Observe que myVarvariável é uma variável inexistente, portanto, seu tipo é indefinido .

A zona de morte temporal evita que você faça referência acidentalmente a uma variável antes de sua declaração.

Resumo

  • As variáveis ​​declaradas usando a letpalavra-chave têm escopo de bloco, não são inicializadas com nenhum valor e não são anexadas ao objeto global.
  • Redeclarar uma variável usando a letpalavra-chave causará um erro.
  • Uma zona morta temporal de uma variável é declarada usando a letpalavra-chave começa a partir do bloco até que a inicialização seja avaliada.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *