Escopo de Função, Escopo de Bloco e Escopo Léxico
Published: 2021-03-25 23:12:08

Chegamos a mais um post da minha [saga de estudos](https://dev.to/inando85/bem-vindo-de-novo-javascript-1b48) em JavaScript.

No post anterior eu falei um pouco sobre a palavra chave `this`, e no final do post, eu falo um pouco sobre o comportamento de seu uso em arrow functions.

O que me fez querer estudar um pouco mais sobre escopo. E por isso, trago neste posts, 3 tipos de escopos que devemos conhecer para entender o funcionamento das aplicações e a forma correta de utiliza-los.

Sabemos que escopo pode ser interpretado como sendo o local de visibilidade de uma variável, e dependendo de onde essa variável é declarada, ela poderá ou não ser acessada de diversos lugares do seu código.


### Escopo de Função

No escopo de função, as variáveis declaradas dentro da função, somente serão acessadas por dentro da função, não sendo possível acessa-las do lado de fora.

No escopo de função, esse comportamento acontece independente da palavra chave usada na criação da variável ou constante, `var`, `let` ou `const`.

```js
function myFunc () {
 let cat = 'Zeca'
 const age = 3
 var color = 'Cinza'

 console.log(cat) // Zeca
 console.log(age) // 3
 console.log(color) // Cinza
}
myFunc()

console.log(cat) // Uncaught ReferenceError: cat is not defined
console.log(age) // Uncaught ReferenceError: age is not defined
console.log(color) // Uncaught ReferenceError: color is not defined
```

A forma de acessarmos as variáveis dessa função fora dela, seria fazer a função retornar um objeto contendo essas variáveis.

```js
function myFunc () {
 let cat = 'Zeca'
 const age = 3
 var color = 'Cinza'

 return { name, age, color }
}

console.log(myFunc().name) // Zeca
console.log(myFunc().age) // 3
console.log(myFunc().color) // Cinza
```

### Escopo de bloco

Escopo de bloco não está relacionado necessariamente a funções, estamos nos referindo por exemplo: `condicional if`, `loop for`,`loop while`.

No escopo de bloco precisamos ficar atentos ao uso das palavras chaves para criação de variáveis, pois se utilizarmos as palavras chaves `let` e `const`, o escopo do bloco será respeitado, mas se utilizarmos a palavra chave `var`, o escopo não será respeitado e a variável poderá ser acessada de qualquer lugar do código, passando com isso a ter o escopo global, de forma automatica.

Usando `let`, a variável só pode ser acessada dentro do bloco:

```js
if (true) {
  let dragon = 'Balerion'
  console.log(dragon) // Balerion
}

console.log(dragon) // Uncaught ReferenceError: dragon is not defined
```

Usando `const` também só poderá ser acessada de dentro do bloco:
```js
if (true) {
  const dragon = 'Balerion'
  console.log(dragon) // Balerion
}

console.log(dragon) // Uncaught ReferenceError: dragon is not defined
```

Usando `var`, a variável não respeita o escopo de bloco e vaza para o escopo global, e com isso, pode ser acessada de qualquer lugar do código.

```js
if (true) {
  var dragon = 'Balerion'
  console.log(dragon) // Balerion
}

console.log(dragon) // Balerion
```

Antes da chegada do ECMAScript 6 (ES6), somente existia a possibilidade de criação de variáveis com a palavra chave `var`.

Um dos motivos para a adição das palavras chaves `let` e `const` no ES6, foi justamente para resolver essa situação de utilização de variáveis em escopos.

### Escopo Léxico

Escopo léxico ocorre quando temos um aninhamento de funções.

Significa dizer que funções aninhadas podem acessar variáveis dentro de outros blocos de funções ao qual façam parte.

O que acontece no exemplo abaixo é que estou tentando acessar a variável `book`, no escopo da função interna, mas não existe uma declaração dessa variável no escopo, com isso, o JavaScript subirá o escopo e buscará pela variável no escopo acima, no caso no escopo da função externa.

Como a variável foi encontrada, a função interna passou a utilizar essa variável.

```js
const externalFunc = () => {
  const book = 'Sapiens'
  
  const internalFunc = () => {
    console.log(book.toUpperCase())
  }
  
  internalFunc()
}

externalFunc() // SAPIENS
```
Mas esta relação segue somente o fluxo de fora pra dentro.

```js
const externalFunc = () => {
  console.log(book.toUpperCase())
  
  const internalFunc = () => {
    const book = 'Sapiens'
  }
  
  internalFunc()
}

externalFunc() // Uncaught ReferenceError: book is not defined
```

É muito importante entender esses 3 escopos, ajudará muito na criação correta de suas aplicações e com certeza, te fará perder menos tempo tentando debugar possíveis erros.

Ficamos por aqui com mais um post.

________________________________________________________________

Esse foi mais um post da minha saga de estudos em JavaScript Vanilla. Espero que estejam gostando!

Qualquer dúvida ou sugestão, vocês me encontram nas minhas redes sociais:

[LinkedIn](https://linkedin.com/in/inando85)
[GIthub](https://github.com/inando85)
[Twitter](https://twitter.com/inando85)