Escopo Lexical em JavaScript – O que exatamente é escopo em JS?
Ivan Trindade
Posted on December 30, 2022
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();
}
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();
}
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();
}
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
:
Primeiramente, o computador verificará se foi
fullName
definido localmente dentro da funçãowriteName()
. Mas não encontrará nenhuma definição defullName
lá, então ele se move para o próximo escopo para continuar sua busca.Em segundo lugar, o computador procurará a definição de
fullName
emsayName()
(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.Em terceiro lugar, o computador procurará a definição de
fullName
na funçãoprofile()
. Ainda assim,fullName
não é encontrado lá. Assim, o computador avança para buscar o escopo lexical defullName
na próxima região da cadeia de escopo.Em quarto lugar, o computador vai para o escopo global (o seguinte escopo após
profile()
). Felizmente, ele encontra a definição defullName
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();
}
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, nemsayName()
,profile()
nem o escopo global podem acessar nenhum dos códigos dewriteName()
.
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;
}
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;
}
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
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"
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ávellastName
deshowLastName()
. Em vez disso,displayFullName()
invocoushowLastName()
— que então retornou o conteúdo de sua variávellastName
.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!
Posted on December 30, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.