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!
Top comments (1)
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.