DEV Community

Cover image for Escopo Lexical em JavaScript – O que exatamente é escopo em JS?
Ivan Trindade
Ivan Trindade

Posted on

Escopo Lexical em JavaScript – O que exatamente é escopo em JS?

O termo "escopo lexical" pode parecer difícil de entender á primeira vista. Mas é útil entender o que cada palavra signicia. Portanto, este artigo explicará o escopo lexical examinando primeiro o significa de "escopo" e "lexical".

Então vamos começar a entender o termo "escopo".

O que é exatamente o Escopo?

Escopo refere-se a área onde um item (como uma função ou variável) é visível e acessível a outro código.

Observação:

  • Escopo significa área, espaço ou região.
  • Escopo global significa espaço global ou um espaço público.
  • Escopo local significa uma região local ou uma região restrita.

Aqui está um exemplo:

// Define uma variável em um escopo global:
const fullName = "Oluwatobi Sofela";

// Definir funções aninhadas:
function profile() {
  function sayName() {
    function writeName() {
      return fullName;
    }
    return writeName();
  }
  return sayName();
}
Enter fullscreen mode Exit fullscreen mode

No trecho acima, definimos a variável fullName no escopo global. Isso significa que é visível e acessível globalmente para todo o código dentro do script.

Mas definimos writeName() dentro da função sayName(), então ela tem escopo local para sayName().

Em outras palavras, writeName() é localmente visível e acessível apenas para codificar na função sayName().

Tenha em mente que sempre que a função writeName() for invocada, o computador não irá direto para o escopo global para chamar a variável fullName. Em vez disso, ele deve passar sequencialmente pela cadeia de escopo para procurar arquivos fullName.

O que é uma cadeia de escopo?

Uma cadeia de escopo refere-se aos espaços exclusivos que existem do escopo onde uma variável foi chamada para o escopo global.

Aqui está um exemplo:

// Define uma variável em um escopo global:
const fullName = "Oluwatobi Sofela";

// Definir funções aninhadas:
function profile() {
  function sayName() {
    function writeName() {
      return fullName;
    }
    return writeName();
  }
  return sayName();
}
Enter fullscreen mode Exit fullscreen mode

No trecho acima, observe que a variável fullName foi chamada do escopo da função writeName().

Portanto, a cadeia de escopo que existe desde a chamada da variável até o escopo global é:

writeName() scope ---> sayName() scope ---> profile() scope ---> global scope

Em outras palavras, há quatro espaços do escopo de invocação do fullName, até seu escopo lexical (o escopo global neste caso).

Como funciona a cadeia de escopo?

A cadeia de escopo do JavaScript determina a hierarquia de lugares pelos quais o computador deve passar — ​​um após o outro — para encontrar o escopo léxico (origem) da variável específica que foi chamada.

Por exemplo, considere o código abaixo:

// Define uma variável em um escopo global:
const fullName = "Oluwatobi Sofela";

// Definir funções aninhadas:
function profile() {
  function sayName() {
    function writeName() {
      return fullName;
    }
    return writeName();
  }
  return sayName();
}
Enter fullscreen mode Exit fullscreen mode

No trecho acima, sempre que a função profile() for invocada, o computador primeiro invocará a função sayName() (que é o único código na função profile()).

Em segundo lugar, o computador invocará a função writeName() (que é o único código na função sayName()).

Nesse ponto, como o código em writeName() instrui o computador a chamar e retornar o conteúdo da variável fullName, o computador chamará fullName. Mas não irá diretamente para o escopo global chamar fullName.

Em vez disso, o computador deve percorrer passo a passo a cadeia de escopo para procurar o escopo léxico de fullName.

Então, aqui estão as etapas sequenciais que o computador deve executar para localizar o escopo léxico de fullName:

  1. Primeiramente, o computador verificará se foi fullName definido localmente dentro da função writeName(). Mas não encontrará nenhuma definição de fullName lá, então ele se move para o próximo escopo para continuar sua busca.

  2. Em segundo lugar, o computador procurará a definição de fullName em sayName()(o próximo espaço na cadeia de escopo). Ainda assim, ele não o encontra lá, então sobe a escada para o próximo escopo.

  3. Em terceiro lugar, o computador procurará a definição de fullName na função profile(). Ainda assim, fullName não é encontrado lá. Assim, o computador avança para buscar o escopo lexical de fullName na próxima região da cadeia de escopo.

  4. Em quarto lugar, o computador vai para o escopo global (o seguinte escopo após profile()). Felizmente, ele encontra a definição de fullName lá! Portanto, ele pega seu conteúdo ( "Oluwatobi Sofela") e o devolve.

Hora de praticar com escopo 🤸‍♂️🏋️‍♀️🏊‍♀️

Considere o script abaixo. Qual das três variáveis fullName ​​o computador chamará?

// First fullName variable defined in the global scope:
const fullName = "Oluwatobi Sofela";

// Nested functions containing two more fullName variables:
function profile() {
  const fullName = "Tobi Sho";
  function sayName() {
    const fullName = "Oluwa Sofe";
    function writeName() {
      return fullName;
    }
    return writeName();
  }
  return sayName();
}
Enter fullscreen mode Exit fullscreen mode

O computador chamará a primeira, segunda ou terceira variável fullName?

Observação: você se beneficiará muito mais com este tutorial se tentar fazer o exercício sozinho.

Se você ficar preso, não desanime. Em vez disso, revise a lição e tente novamente.

Depois de dar o seu melhor (você só vai se enganar se não o fizer!), Vá em frente para ver a resposta correta abaixo.

Você acertou?

Das três definições fullName presentes no script acima, o computador irá chamar e retornar aquela definida na função sayName().

A variável fullName de sayName() será chamada porque sayName() é o escopo dentro do qual o computador encontrará pela primeira vez uma definição fullName.

Portanto, quando profile() for invocado, o valor retornado será "Oluwa Sofe".

Algumas coisas a ter em mente:

  • Suponha que o computador não tenha encontrado a definição de fullName em nenhum dos escopos. Nesse caso, o computador retornará Uncaught ReferenceError: fullName is not defined.

  • O escopo global é sempre o último escopo de qualquer cadeia de escopo JavaScript. Em outras palavras, o escopo global é onde todas as pesquisas terminarão.

  • Um escopo interno (filho) tem acesso a seu escopo pai (externo), mas um escopo externo não tem acesso a seu escopo filho.
    Por exemplo, no snippet acima, writeName() pode acessar códigos dentro de qualquer escopo pai (sayName(), profile() ou o escopo global).
    No entanto, nem sayName(), profile() nem o escopo global podem acessar nenhum dos códigos de writeName().

Revisão rápida do escopo até agora

O escopo do JavaScript tem tudo a ver com espaço.

Então, da próxima vez que seu parceiro chamar você para seu espaço privado, lembre-se de que ele está convidando você para seu espaço privado 😜!

Quando você chegar lá, pergunte a eles sobre o melhor jogo lexical deles...

Mas o que significa léxico, ouvi você perguntar? Vamos descobrir abaixo.

O que significa Lexical?

Lexical refere-se à definição das coisas.

Qualquer coisa relacionada à criação de palavras, expressões ou variáveis ​​é denominada lexical.

Por exemplo, um jogo de scrabble é uma atividade lexical porque se relaciona com a criação de palavras.

Além disso, alguém cujo trabalho esteja relacionado à lingüística (o estudo das línguas) tem uma carreira lexical.

Nota: Outro nome para um dicionário é léxico. Em outras palavras, um léxico é um dicionário onde as palavras são listadas e definidas.

Agora que sabemos o que significa escopo e léxico, podemos falar sobre escopo lexical.

O que é escopo léxico em JavaScript?

Escopo léxico é a área de definição de uma expressão.

Em outras palavras, o escopo léxico de um item é o local em que o item foi criado.

Observação:

Outro nome para escopo léxico, é escopo estático.
O local em que um item foi invocado (ou chamado) não é necessariamente o escopo lexical do item. Em vez disso, o espaço de definição de um item é seu escopo léxico.

Exemplo de Escopo Lexical

Considere o código abaixo:

// Define a variable in the global scope:
const myName = "Oluwatobi";

// Call myName variable from a function:
function getName() {
  return myName;
}
Enter fullscreen mode Exit fullscreen mode

No trecho acima, observe que definimos a variável myName no escopo global e a chamamos na função getName().

Pergunta: Qual dos dois espaços é o escopo lexical de myName? É o escopo global ou o escopo local da função getName()?

Resposta: Lembre-se de que escopo léxico significa espaço de definição — não espaço de invocação. Portanto, o escopo lexical de myName é o escopo global porque definimos myName no ambiente global.

Outro exemplo de escopo lexical

function getName() {
  const myName = "Oluwatobi";
  return myName;
}
Enter fullscreen mode Exit fullscreen mode

Pergunta: Onde está o escopo lexical de myName?

Resposta: Observe que criamos e chamamos nyName dentro de getName(). Portanto, o escopo léxico de myName é o ambiente local de getName(), porque getName() é o espaço de definição de myName.

Como funciona o escopo lexical?

O ambiente de definição de uma expressão JavaScript determina o código permitido para acessá-la.

Em outras palavras, apenas o código dentro do escopo léxico de um item pode acessá-lo.

Por exemplo, considere o código abaixo:

// Define a function:
function showLastName() {
  const lastName = "Sofela";
  return lastName;
}

// Define another function:
function displayFullName() {
  const fullName = "Oluwatobi " + lastName;
  return fullName;
}

// Invoke displayFullName():
console.log(displayFullName());

// The invocation above will return:
Uncaught ReferenceError: lastName is not defined
Enter fullscreen mode Exit fullscreen mode

Observe que a invocação de displayFullName() no snippet acima retornou um ReferenceError não capturado. O erro retornou porque apenas o código dentro do escopo léxico de um item pode acessar o item.

Portanto, nem a função displayFullName() nem seu código interno podem acessar a variável lastName, porque lastName foi definido em um escopo diferente.

Em outras palavras, o escopo léxico de lastName é diferente daquele de displayFullName().

O espaço de definição de lastName é showLastName() enquanto o escopo léxico de displayFullName() é o ambiente global.

Agora, considere este outro código abaixo:

function showLastName() {
  const lastName = "Sofela";
  return lastName;
}

// Define another function:
function displayFullName() {
  const fullName = "Oluwatobi " + showLastName();
  return fullName;
}

// Invoke displayFullName():
console.log(displayFullName());

// The invocation above will return:
"Oluwatobi Sofela"
Enter fullscreen mode Exit fullscreen mode

O snippet acima, displayFullName() retornou com sucesso "Oluwatobi Sofela" porque displayFullName() e showLastName() estão no mesmo escopo léxico.

Em outras palavras, displayFullName() poderia invocar showLastName(), porque as duas funções são definidas no escopo global.

Observação:

  • No exemplo 2 acima, displayFullName() não obteve acesso à variável lastName de showLastName(). Em vez disso, displayFullName() invocou showLastName() — que então retornou o conteúdo de sua variável lastName.

  • Uma alternativa ao escopo léxico, é o escopo dinâmico — mas raramente é usado na programação. Apenas algumas linguagens, como bash, usam escopo dinâmico.

Conclusão

Sempre que você ouvir lexical, pense na definição.

Assim, o escopo lexical de um carro, variável, telefone, função ou maiô refere-se à sua região de definição.

Este artigo discutiu o que significa escopo léxico em JavaScript. Também vimos por que é um importante conceito de programação.

Obrigado por ler!

Top comments (1)

Collapse
 
szabgab profile image
Gabor Szabo

Hi,

I think it would be useful if you added the appropriate language tag to each one of your posts. Portuguese if I am not mistaken.