Concrete Logo
Hamburger button

Entendendo hoisting e escopo, o que mudou no ES2015 - Parte 2

  • Blog
  • 13 de Setembro de 2016

*Este post foi originalmente publicado no Medium pessoal do autor. Confira aqui.

Comecei ontem aqui no Blog uma série para entendermos hoisting e escopo no ES2015. Se você não viu, clique aqui. Ontem, falamos sobre escopo, e a ideia hoje é falar sobre hoisting. Vamos lá?

O que é Hoisting ?

Hoisting: Levante (algo) por meio de cordas e polias. Sinônimos: levantar, levantar-se, elevador, transportar-se, erguer-se, subir, suba, guincho para cima, puxar para cima, elevar.

 

Em tempo de execução, todas as variáveis e declarações de funções são movidas para o início de cada função (seu próprio escopo), independentemente de onde eles são declarados  –  isso é conhecido como elevação (hoisting). Dito isso, é uma boa prática declarar todas as variáveis juntas na primeira linha, a fim de evitar falsas expectativas em relação a uma variável que foi declarada depois mas que acabou recebendo um valor antes.

No entanto, somente a declaração será hoisted (elevada). Se a variável é também inicializada o valor no topo do escopo será inicialmente configurado para undefined.

JavaScript Hoisting

Vamos vê-lo em ação:

Que é interpretado e executado:

E por que eu devo me importar ?

O código acima está tudo ok até o momento. Vamos fazer algumas modificações.

O primeiro console vai te retornar The value of variable: undefined e o segundo The new value of varible: I love Javascript!!! Para muitos, o valor undefined é bem estranho, principalmente para desenvolvedores C (e sua família), além dos novos com Javascript. Mas vamos entender o porquê disto:

Eu sei que é bem estranho, mas por padrão devemos adotar que toda declaração de variáveis fiquem no início do seu código, evitando bugs.

Function Hoisting

As funções também são elevadas (hoisted):

O interpretador de JavaScript permite que você use uma função antes de ser declarado no código-fonte.

No entanto, a função de elevação ocorre apenas para funções declaradas, e não para funções anônimas.

No exemplo de código acima vemos a interação de dois tipos diferentes de hoisting. Nossa variável fnNotHoisting tem a sua declaração hoisting, mas não o seu valor, que é undefined. Funções anônimas não são hoisting.

E o que mudou no ES2015?

Bem, com o ES2015 uma das boas mudanças foi a chegada de variáveis com let e escopo. Esta novidade permite declarar variáveis limitadas ao âmbito de um bloco. É o oposto do var, por declarar e sobrescrever variáveis no âmbito global de sua função envolvente.

O let vai fazer hoisting da variável no topo do bloco, ou seja, caso seja declarado novamente no mesmo contexto, a segunda declaração retornará um TypeError. E caso a variável definida com let seja referenciada antes da sua declaração, o erro será de referência.

Vamos ver um exemplo com let:

No código acima temos as funções helpMe() e imHere(). Na função helpMe a variável location pode ser acessada fora do bloco if. Por isso, quando chamamos a variável phrase é retornado o resultado:

Me ajude, localização -> -23.5193987,-46.1895406

Diferentemente, na função imHere a variável here nos retorna:
ReferenceError: here is not defined.

Isso acontece porque ela está definida dentro do bloco if, podendo ser acessada somente neste bloco.

Diferença entre var e let

Com var é possível redeclarar a mesma variável, mas o mesmo não acontece com let. Vamos ver um exemplo:

Com var podemos ler a variável mesmo que o código ainda não tenho sido inicializado. Com var isso vai retornar undefined, com let ivai te retornar um erro. Veja a seguir:

Outro algo novo que surgiu é a Const. Em ES6, uma const representa uma referência constante para um valor. Em outras palavras, o valor não está congelado, apenas a atribuição dele.

Algumas coisas para lembrar:

  • let e const são escopadas aos fechamentos de bloco mais próximos;
  • Quando usar const, use CAPITAL_CASING;
  • hoisting” de let e const variam da forma tradicional de “hoisting” de variáveis e funções. Ambos estão “hoistados”, mas não podem ser acessados antes das suas declarações.
  • const deve ser definida na sua declaração.

Ficou alguma dúvida ou tem algum comentário? Aproveite os campos abaixo. Até a próxima!