A Próxima Geração JavaScript [Let & Const]
Tags: javascript, frontend, devweb
Published: 2020-10-08 23:25:55

`let` e `const` são formas de declararmos variáveis e constantes a partir da versão 6 do `ECMAScript`.

Mas antes de entendermos quais as diferenças entre o nosso queridinho `var` é importante voltarmos um passo atrás e entendermos como ele se comporta em aplicações `js`.

###**Hoisting**

Em JavaScript, toda variável é **“elevada/içada” (hoisting)** até o topo do seu contexto de execução. Esse mecanismo **move as variáveis para o topo do seu escopo antes da execução do código**. Independentemente de onde a declaração real ocorrer.

O que faz com que variáveis possam estar disponíveis antes de sua declaração. 

Vejamos um exemplo:

```javascript
var exibeIdade = function() { 
    idade = 27; 
    console.log(idade);
    var idade;
}
```

Caso você esteja familiarizado com linguagens baseadas em C, talvez estivesse esperando que um erro fosse lançado ao chamar 
 `console.log(idade)` já que a variável `idade` ainda não havia sido definida. 

Porém, o interpretador do Javascript **“eleva/iça”** todas as declarações de variáveis até o topo do seu contexto de execução, embora suas inicializações permaneçam no mesmo local.

Sendo assim a função imprimiria o valor `27`.

```javascript
exibeIdade(); // imprimi 27 
```


###**Variáveis undefined** 

Beleza, já sabemos que é possível atribuirmos um valor à uma `var` antes de sua declaração. Mas o que acontece com o seguinte código:

```javascript
void function(){ 
    console.log(texto); 
}();
var texto;
```

No caso da palavra-chave `var`, além da variável ser **içada (hoisting)** ela é **automaticamente inicializada com o valor `undefined`**, caso não seja atribuído nenhum outro valor.

Agora você deve estar se perguntando: ***E qual o problema desse comportamento***? 

Imagine que seu código contenha muitas linhas e que sua complexidade não seja algo tão trivial de compreender.

Às vezes, queremos declarar variáveis que serão utilizadas apenas dentro de um pequeno trecho do nosso código. **Ter que lidar com o escopo de função das variáveis declaradas com `var`  pode confundir a cabeça até de programadores mais experientes.**

Foi pensando nesses problemas que os nossos amiguinhos do `ECMAScript 6` introduziram **escopos no nível de bloco (block-level scoping)** para prover aos desenvolvedores maior controle e flexibilidade sobre o ciclo de vida de uma variável.

###**Let** 

Através da palavra-chave `let` podemos declarar variáveis com escopo de bloco. 
Veja um exemplo:

```javascript
var exibeTexto = function() {
     if(true) { 
         var escopoFuncao = 'Frontend'; 
         let escopoBloco = 'Dev';

        console.log(escopoBloco); // Dev 
    } 
    console.log(escopoFuncao); // Frontend 
    console.log(escopoBloco); 
}

```

O código acima terá a seguinte saída:

```javascript
exibeTexto(); // Imprime 'Dev', 'Frontend' e dá um erro
```

Quando nós tentamos acessar uma variável que foi declarada através da palavra-chave `let` fora do seu escopo, o erro `Uncaught ReferenceError: escopoBloco is not defined` foi apresentado.

Sendo assim, podemos utilizar tranquilamente o `let`, pois o escopo de bloco estará garantido. 😉

###**Const** 

Embora o `let` garanta o escopo, ainda assim, existe a possibilidade de declararmos uma variável com `let` e a mesma ser `undefined`. 
Por exemplo:

```javascript
void function(){ 
    let texto; 
    console.log(texto); // Imprime undefined 
}();
```

Caso nós tenhamos uma variável e desejamos garantir que sua inicialização seja com um determinado valor, como podemos fazer isso no JavaScript sem causar uma inicialização padrão com `undefined`?

Para termos esse tipo de comportamento em uma variável no `JavaScript`, podemos declarar `constantes` por meio da palavra-chave `const`. 
Veja um exemplo:

```javascript
void function(){ 
    const texto = 'Frontend é supimpa'; 
    console.log(texto); // Frontend é supimpa'
    texto = 'Backend é mais legal'; 
}();
```
A syntax dessa declaração é similar a `let` e ao `var`, o ciclo de vida(lifecycle) é o mesmo que o do `let`, porém com algumas regras.

Toda `const` é tratada como `constante`, e, portanto, ela não pode ter seu valor alterado após ser definida. Sendo assim, toda `const` **deve ser inicializada com um valor** no momento de sua declaração.

Logo o código acima gera um `Uncaught TypeError: Assignment to constant variable`, pois o comportamento fundamental de uma constante é que **uma vez atribuído um valor a ela, este não pode ser alterado**.

Outro exemplo:

```javascript
// constante válida 
const nome = 'João';

// constante inválida: onde está a inicialização? 
const idade;
```

No código acima temos o exemplo de uma constante nome sendo declarada e inicializada na mesma linha e um outro exemplo onde o valor não é atribuído na declaração de idade ocasionando o erro `Uncaught SyntaxError: Missing initializer in const declaration`.

É muito importante utilizar `const` para declarar nossas variáveis, porque assim conseguimos um comportamento mais previsível, já que o valor que elas recebem não podem ser alterado e o escopo dela também é em bloco.

###**Conclusão** 

![Captura de Tela 2020-10-09 às 00.54.16](https://dev-to-uploads.s3.amazonaws.com/i/4fsmv0dkhaqyp1t8slh7.png)


______________________________________________________________


*Referências*:
[const vs let vs var in JavaScript](http://www.constletvar.com/)
[A guide to JavaScript variable hoisting](https://www.freecodecamp.org/news/what-is-variable-hoisting-differentiating-between-var-let-and-const-in-es6-f1a70bb43d/)
[Entenda a diferença entre var, let e const no JavaScript](https://www.alura.com.br/artigos/entenda-diferenca-entre-var-let-e-const-no-javascript)