Transcrições
1. Apresentação: Estamos em uma nova seção
com tópicos interessantes. Nesta seção,
trataremos de alguns tópicos que são realmente
centrais para o JavaScript. Todos esses tópicos
estão centrados nas funções e na
natureza das funções. Esses conceitos levaram a
muitos dos padrões que
definiram um alto nível de especialização em
desenvolvimento. E é importante que
você entenda e seja
capaz de aplicar o que está nesta
seção em sua própria codificação. Primeiro, falaremos sobre a natureza das funções
em JavaScript. A função JavaScript é muito poderosa porque é
uma cidadã de primeira classe. E as funções podem ser usadas
em uma ordem superior. Vamos analisar o encerramento, um recurso que eu acho que é um
dos recursos mais úteis e
poderosos da linguagem JavaScript. Vamos lidar com a invocação
imediata funções e com o
padrão em torno disso. Portanto, temos muito a cobrir. Então, vamos começar.
2. As funções são cidadãos da primeira classe: No início deste curso, falei sobre como os objetos
estão em toda parte em JavaScript, com exceção
dos primitivos, todo
o resto é um objeto. Então, como discutimos na
época, funções são objetos. O fato de funções serem objetos é uma característica
muito importante. Isso faz com que funções sejam cidadãos
de primeira classe
em JavaScript. Agora, a ideia de que as funções
são de primeira classe
significa simplesmente que as funções são tratadas como valores que podem
ser transmitidos. E como funções são objetos, é
isso que torna
isso possível. Então, quando pensamos em um valor, normalmente
pensamos em algo
como uma string ou um número. Em qualquer lugar, um valor como uma string ou um
número pode ser usado. Uma função
também pode ser usada porque é
tratada como valores, o que a torna de primeira classe. Para consolidar essa ideia, vamos dar uma olhada em vários exemplos em que valores tradicionais podem ser usados e mostrar que uma função pode ser usada
no mesmo local. Agora, os dois primeiros exemplos
são bastante óbvios. Podemos atribuir um valor como
um número a uma variável. Bem, também podemos atribuir uma função
a uma variável. E já fizemos muitas
vezes em qualquer momento que
criamos uma expressão de função
como a mostrada aqui. Estamos atribuindo essa
função a uma variável. Isso é muito comum. Isso não é estranho
para nós neste momento. Agora, antes de mostrar
esse segundo exemplo, que também é
bastante óbvio, quero mostrar algo sobre as funções aqui e como elas são
atribuídas à variável. Nós nos divertimos dez. Agora, e se eu
fizesse algo assim? E se eu criasse
outra variável? E é divertido dez por e define
isso como um fundo de dez. Então, o que está acontecendo aqui? Porém, como as funções são
objetos, o que
ela está fazendo é atribuir uma referência a essa mesma função aqui. Atribuir outra
referência ao fundo a. Não é invocar
a função e colocar um dez em Fontan. Lembre-se de que essa é uma diferença
distinta. Temos que usar parênteses
para invocar uma função. Então, vamos ver
isso bem rápido. Se fôssemos ver a diversão
dez a no console, deixe-me abrir isso. Vemos que é uma função. Isso é o que estamos
vendo aqui como uma função. No entanto, se invocarmos Fontan a colocando
impressões depois dela, obteremos as dez retornadas, que é o que essa função
deve fazer. Ponto tão importante sobre o
uso da variável à qual uma
função está atribuída. Se não colocarmos
parênteses depois dela, ela não invocará
essa função. Tudo bem, agora, o segundo exemplo
que queremos ver, vou apenas
rolá-lo aqui é uma função que pode ser atribuída
a uma propriedade de um objeto. Agora, já vimos isso
muitas vezes. É por isso que essa também é
óbvia. Basicamente, const OBJ e defina isso como igual a um
objeto como este. E então, se fizermos cólon
divertido, aqui é onde colocaríamos a função
atribuída a ele. E este só
vai ser divertido. Agora, lembre-se de invocar isso, usamos a sintaxe de pontos. Simplesmente fazemos OBJ dot e , nesse caso, qualquer propriedade à qual seja atribuída, é divertida. Mais uma vez, usamos as impressões
duplas para invocá-la. Está bem? Agora, isso, como vimos antes, pode ser feito com um método de
atalho como esse. Isso faria
a mesma coisa, configurando uma função lá. E nos divertimos
entrando no console. Vou fechar isso
um pouco para que possamos configurar o console. Tudo bem, então esse é
o segundo. Esses eram
muito óbvios. Então, a terceira, talvez não seja tão óbvia. E esta é uma função que
pode ser armazenada em uma matriz. Então, vamos configurar uma matriz aqui. E vamos colocar
um número lá. Um valor pode entrar em uma matriz, já
sabemos disso, mas podemos colocar uma função
lá também? Bem, sim, nós podemos.
E desta vez eu vou fazer uma função de seta. Basicamente, só
vai retornar dez, como fizemos no passado. Então, agora temos uma função na segunda posição
dessa matriz. E podemos invocar isso
usando as tendências novamente. Então, temos que
indicar a posição na matriz dessa forma. E então colocamos amigos
depois disso, vamos invocá-lo. Então, isso deve retornar dez. Então, se
registrarmos isso no console, desse
jeito, deveríamos
obter dez no console. E aí vamos nós. Eu
comentei isso aqui em cima, então assiste à única coisa que
estamos vendo lá em cima. Assim, um valor pode ser armazenado em uma matriz e uma função
pode ser armazenada em uma matriz. Agora, uma função pode fazer parte de uma expressão,
assim como um valor. Vamos dar uma olhada neste. Vou fazer um registro simples
do console lá dentro. Vou colocar uma
expressão para que
possamos ver os resultados
dessa expressão. Aqui está a expressão. Eu só vou
fazer 30 mais o quê? Bem, vamos
fazer uma função. Então, vou declarar
uma função aqui. E eu vou fazer com
que ele retorne às 10. Agora. No momento, isso
não vai somar 30 mais dez porque essa
função não é invocada. Acabamos de declarar isso aqui. Então, se fôssemos salvar isso, deixe-me comentar que,
se salvarmos
isso, ele apenas concatena o texto dessa função
com o número 30. No entanto, se fôssemos
invocá-lo e isso o invocasse
imediatamente. E esse é um tópico que
discutiremos
nesta seção com
mais detalhes posteriormente. Mas se eu colocar
impressões duplas logo depois disso, agora vamos ver o que acontece. Agora. Ele invoca a função, retorna um tan e
depois adiciona 30 a dez. Então, colocamos uma função como
parte de uma expressão, assim como poderíamos fazer
qualquer outro valor. Agora, para fazer a mesma coisa, só para que você saiba fazer
a mesma coisa com
uma função de seta, você precisaria fazer
algo assim, mais de 30. E então aqui está nossa função de
seta. E se definirmos aquela
seta gorda de retornar dez, isso é ótimo, exceto que não podemos
colocar marcas imediatamente depois disso. Temos que colocar
tudo entre parênteses, assim. Em seguida, podemos colocar
parênteses depois disso. Agora devemos chegar às declarações de
registro do console aos
40. E aí vamos nós. Então é assim que você faria
isso com uma função de seta. Agora, no próximo exemplo, podemos passar valores
para uma função. Um número pode ser passado
para uma função de string, pode ser passado na função. Bem, então as funções podem ser
passadas para as funções? Então, pense em retornos de chamada. Fizemos muito com retornos de chamada. E esse é um exemplo
de onde estamos passando uma função
para outra função. Portanto, o exemplo
mais comum que provavelmente fizemos neste
curso é o uso de setTimeout. Portanto, setTimeout tem
dois parâmetros. Uma é uma função que
passamos e a outra é a quantidade de tempo
em milissegundos. Então, isso seria 1 s lá. Esse primeiro parâmetro é
apenas uma função que passamos. E eu posso fazer uma
função de seta lá para esta. E vamos apenas console dot log. O tempo acabou, algo assim. Então, aqui estamos passando uma
função para outra função. Então, se dissermos isso, obtemos 240 e,
um segundo depois,
obtemos o tempo que acabou
exibido no console. Agora, o exemplo final que
queremos ver é que uma função pode ser
retornada de uma função. Então, aqui embaixo. Assim como podemos passar uma
função para uma função, também
podemos retornar uma. Então, deixe-me configurar
algo, me divertir. Defina isso como igual. Estamos declarando uma função aqui. E o que vamos devolver? O que vamos
devolver como função. Vou declarar isso aqui após a declaração de devolução, e teremos apenas
um registro do console. Vamos ver, eu voltei. Como fazer isso? Então essa é a nossa declaração de devolução. E o que estamos retornando? Bem, poderíamos retornar um número, podemos retornar uma string, podemos retornar uma função porque ela é tratada como um valor. Então, agora, com essa configuração, se usarmos um novo fundo, vamos armazenar
a função aqui
que foi retornada
e igualá-la
para nos que foi retornada
e igualá-la divertir e usar o
príncipe para invocá-la. Vá em frente e salve isso. Aqui estão
os registros do nosso console que temos lá em cima. Mas agora vamos ver o que o
novo fundo contém. Agora, se eu colocar uma nova diversão
aqui sem as marcas, vou ver o texto
dessa função. Mas se eu me divertir com
marcas e fazer com que elas
invocem, obtemos o valor de retorno. Temos a declaração de
registro do console, não o valor de retorno. Então, aí estamos retornando
uma função. Agora, algo que podemos fazer aqui. Atribuí a
função de retorno a uma variável, mas também poderia simplesmente ligar e
me divertir assim. E isso
retornará uma função. Bem, e se quiséssemos invocar essa função
que é retornada? Podemos simplesmente inserir outro
conjunto de planos logo após ele. Portanto, essas primeiras impressões atuam
na função get fun. O próximo conjunto de marcas age sobre essa função que é retornada e faz com que essa
função seja invocada. Então, agora, se seguirmos
em frente e
salvarmos isso, veremos que eu
voltei ao console. E aí está nosso
olho de volta. Aqui está nossa declaração de registro
do console setTimeout. Portanto, há um total de seis exemplos de como
podemos usar uma função, assim como
usaríamos qualquer outro valor, como um número ou uma string, porque uma função em
JavaScript é tratada como um valor e é
por isso que é de primeira classe. É por isso que chamamos funções
em JavaScript de primeira classe. Tudo bem, agora, esses
dois últimos exemplos que
analisamos, vamos nos
aprofundar em mais detalhes
no próximo tópico quando falarmos
sobre funções de ordem superior.
3. Funções de ordem superior: No tópico anterior, mostramos como as funções em
JavaScript são tratadas como de primeira classe porque são
tratadas como outros valores. Neste tópico, vamos expandir essa ideia
ao falarmos sobre funções de
ordem superior. Funções de ordem superior
são simplesmente funções que atuam em outras funções seja tomando-as como argumento ou
retornando uma função. Vimos exemplos disso
no tópico anterior. Na verdade, os dois últimos exemplos mostraram funções de ordem superior. O fato de o JavaScript
suportar funções de primeira classe torna possível criar funções
de ordem superior. Portanto, o conceito de
funções de primeira classe explica como as funções são tratadas em
JavaScript como valores. O conceito de funções de
ordem superior explica como as usamos. Agora, aqui estão os dois
últimos exemplos que usamos no tópico anterior. Temos um tempo limite definido e estamos passando
uma função aqui. E também temos
outro parâmetro que é a quantidade de tempo. Portanto, o fato de podermos usar uma função como
parâmetro e passá-la faz com que essa função atue na função setTimeout
atuando em outras funções. Este é o que foi
transmitido e está agindo. Então, por causa disso, é uma função de ordem superior. Aqui embaixo. Isso
gera uma função divertida. Essa retorna uma
função e , como está agindo
em outras funções, é uma função de ordem superior. Então, basicamente,
as funções de ordem superior recebem funções como um parâmetro
ou as retornam. Então, entendemos o que são funções de
ordem superior, mas por que elas são tão importantes? Agora, a
aplicação mais comum de funções de
ordem superior em
JavaScript é o callback. Existem vários métodos em JavaScript que nos permitem passar uma função que será usada como parte desse método ou função. Então, ele será chamado de volta. Sempre que criamos
um ouvinte de eventos, configuramos um retorno de chamada. Por isso, eles são muito
comuns em JavaScript. Agora, quero usar a
função setTimeout como exemplo e dissecar por que ela é melhor como
uma função de ordem superior, o que a torna melhor? Então, vou para um arquivo de
código diferente agora, onde já tenho duas funções
setTimeout criadas. Agora, primeiro, quero me
concentrar no último parâmetro, que é a quantidade de milissegundos que
o setTimeout executa. Então, estamos passando dados para lá. Ao passar dados para
essa função setTimeout, ela a torna mais flexível. Em vez de chamar uma função
setTimeout que sempre é executada por 3 s, podemos passar o número de milissegundos que
queremos que ela seja executada. E valerá para esse número. Portanto, ao ser
capaz de transmitir dados, torna a função
mais flexível. Também nos ajuda a evitar que
repitamos o código. Se tivéssemos que ter uma função
setTimeout
que funcionasse por 3 s e
outra que funcionasse por 4 s. Eles basicamente estão fazendo coisas
muito semelhantes, apenas por uma quantidade de tempo diferente. Então, ao sermos capazes de
transmitir dados como
fizemos aqui, mantemos esse princípio básico. Não se repita. Não repita o código. Fazemos isso passando
um parâmetro. Bem, a mesma coisa pode ser dita para passar uma função, para criar uma função
de ordem superior. Os dados que transmitimos
controlam sua flexibilidade. Com base em quais dados ele pode agir. A função que
passamos controla sua flexibilidade,
afetando seu aspecto funcional. Então, vamos dar esses
dois exemplos. Eu tenho um setTimeout que, após um segundo, é simplesmente registrado no registro
do console. Esse é um exemplo. Eu tenho um setTimeout
aqui embaixo que, após 2 s, ele registra ou retorna
dois mais dois. Esse é outro exemplo. Agora, é possível que para
atender a esses dois requisitos
funcionais, pudéssemos ter criado uma
função de log setTimeout que toda vez ela era chamada de registro de
algo no console, acabamos de passar os
dados que queríamos registrar. E podemos criar uma função de
adição setTimeout que, toda
vez que era chamada, adicionava alguns números
depois que o tempo expirasse. Seriam duas funções
distintas. E estaríamos repetindo o código. Mas como setTimeout
é de ordem superior, podemos passar uma função
que pode fazer qualquer coisa. Portanto, é mais flexível. Alguns podem argumentar
que é mais complexo. E acho que é quando
você aprende sobre isso pela primeira vez, quando você aprendeu sobre funções de
ordem superior e compreende
como usá-las. Mas uma vez que você está
familiarizado com eles, realmente não
é
muito mais difícil. Realmente não é. E a flexibilidade
se torna muito poderosa. Então, todo esse conceito de seco, não se repita, é uma das razões pelas quais
queremos ter funções de ordem superior. Agora, como mencionei,
o JavaScript está cheio de funções de ordem superior. Os métodos em muitos
dos diferentes tipos são funções
de ordem superior. Por exemplo, matrizes têm vários
métodos que são de ordem superior. Eles aceitam uma função
como parâmetro e, em seguida, fazem algo usando a função
que é passada. Mas eu só quero
ressaltar e alertar você que funções de ordem superior são encontradas em todo o JavaScript. Acho que algumas pessoas que são novas JavaScript ou estão
começando em JavaScript as
evitam porque parecem complexas, mas você não pode evitá-las. Eles são tão poderosos. Tudo bem, vamos
passar para o próximo tópico.
4. Criando sua própria função de ordem mais alta: Há muitos métodos
em JavaScript que tiram proveito de funções de
ordem superior. Eles resolvem problemas usando padrões que tiram proveito dessas funções de ordem superior. E podemos aprender com isso
e usá-lo em nossa própria cor. Como apenas um exemplo, vamos analisar esse método de classificação que está disponível para matrizes. Aqui eu tenho duas matrizes, uma com nomes e
outra com números, e vamos classificá-las. Então, vamos fazer os nomes e
também números como esses. Em seguida, dê uma olhada nos resultados. Então, se guardarmos isso, deixe-me ir
até o console novamente. E agora examinamos essas
duas matrizes, nomes e números. Podemos ver que, com os nomes, as coisas estão ordenadas corretamente. Eles são classificados em
ordem alfabética. Mas o que o método de classificação
faz com os números é convertê-los em
uma string e depois classificá-los alfabeticamente
com base na string. E então estamos recebendo
algumas coisas muito estranhas aqui com números. Portanto, classificar por si só
não é ideal para números. No entanto, o método de classificação foi
configurado para usar uma função
de ordem superior, uma função de comparação,
como parâmetro. Podemos passar uma função
para o método de classificação. Ele usará essa função para
fazer uma comparação de elementos. Ele examinará cada elemento,
dois de cada vez,
pela matriz e
os comparará com base na
função que passamos. E então isso
determinará a ordem de classificação. Agora, a forma como isso funciona é se o primeiro
argumento for passado. Então, quando criamos nossa função, ela passa os dois
primeiros elementos. Se o primeiro argumento
aparecer antes do
segundo argumento
, precisamos
garantir que nossa função retorne um número menor que zero. Se o segundo argumento
vier antes do primeiro argumento do que um número maior que zero, ele
deverá ser retornado. Agora, pense na
vantagem disso. Vamos fazer isso
em apenas um minuto. Mas pense
na vantagem de que esse método de classificação não se limita
mais
apenas à classificação de cadeias de caracteres. Agora podemos fazer com que ele
classifique outras coisas porque ele aceita uma função
como um de seus parâmetros. E ele usa essa função
e a chama para, nesse caso, os elementos dois de cada vez
ao transmiti-los. Então, vamos tentar isso com números. Então, vou
passar uma função. E, como eu disse, essa função precisa
aceitar dois parâmetros. Ele aceitará
os dois primeiros elementos, e assim por diante, à medida que funciona
nessa matriz. Agora, como precisamos retornar
um número menor que zero, se o primeiro argumento
se tornar, deveria vir antes
do segundo argumento, podemos fazer algo assim, retornado a menos b. E isso fará uma ordem de classificação. Do menor para o maior. semana poderia reverter isso
indo na outra direção. Porque olha, se 100 é passado e 95 é passado
para a e B, 100 -95 é igual a cinco. Então esse é um número maior que zero. E isso significa que o segundo argumento virá
antes do primeiro argumento, então colocará 95 antes de 100. Agora, ele vai comparar
todos esses números e colocá-los em uma ordem
ordenada.
Saiba como fazer isso. Tudo o que precisamos fazer é passar a função como
fizemos aqui. Então, se salvarmos isso e dermos uma
olhada nos números novamente, veremos que é
menor para maior. Portanto, vários métodos em JavaScript
tiram proveito disso. A capacidade de aceitar uma função
e chamá-la quando necessário. E podemos fazer a mesma
coisa em nosso código. Também podemos tirar
proveito disso. Digamos que eu quisesse criar uma função que
processa cadeias de caracteres. Deixe-me copiar
isso aqui e depois
falaremos sobre isso. Aqui está minha função que
processa cadeias de caracteres. Permitimos que uma string
seja passada
e, em seguida, convertemos essa automaticamente em
maiúsculas. Isso é o que fazemos nessa função de cadeia
de caracteres de processo. Estou tentando
simplificar para que possamos manter essas
informações de retorno de chamada, o foco. Então, ele o
converterá em letras maiúsculas. No entanto, se enviarmos um
retorno de chamada, ele fará mais. Ele fará tudo o que
indicarmos com uma função. Então, de repente, essa função
é muito mais poderosa. Ele pode fazer muito mais. Agora observe como lidamos
com o retorno de chamada. Criamos uma nova string
com duas letras maiúsculas. Mas depois verificamos se o tipo de retorno de chamada
é igual à função. Então, se algo foi passado
e é uma função, então vamos invocá-lo. E passe essa nova string que já fizemos,
a conversão em maiúsculas. Esse retorno de chamada faz o que
é necessário e o retorna. E então retornamos esse valor. Se não houver retorno de chamada, apenas
retornaremos a nova
string que criamos. Então, isso pode lhe dar uma ideia, um padrão para criar funções que são
muito mais flexíveis muito mais poderosas. Agora vamos seguir em frente
e tentar isso. Vamos usá-lo para que
possamos ver como funciona. Tudo bem, vou
fazer um registro do console. Portanto, quero registrar
os resultados do que é retornado da string processada ou da string
processada no console. Então eu chamo de fluxo de processo, essa função ali mesmo. E eu vou
passar uma corda. Então, vamos
montar uma corda aqui. Const STR one. Vou apenas igualar isso a. Isso é uma string, algo simples assim. Então, queremos passar isso no STR um para essa função de
fluxo de processo. Agora queremos repassar
uma chamada de retorno. E eu vou configurar
esse retorno de chamada aqui. Então eu entro na função, será uma função
anônima. Há uma cinta encaracolada, agora
eu posso definir o que ela faz. Mas uma coisa que precisamos
fazer é garantir que
coloquemos uma variável aqui para o parâmetro que
vou
chamar de vogal de valor. Porque veja o que está
acontecendo aqui. Está passando esse novo fluxo
para essas funções de retorno de chamada. Então, precisamos ter
certeza de que aceitamos isso, aceitamos e depois
fazemos algo com ele. Bem, digamos que tudo o
que queremos fazer criar uma matriz a
partir dessa string que será dividida no espaço. Então, usamos o método split
e dividimos no espaço. Então, retornaremos isso
assim que fizermos isso. Então, aqui está o método de divisão. E então colocamos espaço lá como o que
queremos dividir. Então, o que devemos obter, o que devemos
registrar no console é essa string toda em letras maiúsculas? Dentro de uma matriz em cada
palavra estará em sua, seja seu próprio elemento na matriz. Por isso, tornamos nossa função de fluxo de
processo mais poderosa e flexível,
tornando-a mais ordenada. Então, vamos salvar
isso e dar uma olhada. E aí temos uma matriz. Tudo em
letras maiúsculas, cada palavra, seu próprio elemento na matriz. Então, o que eu quero que você
tire disso é o poder das funções de
ordem superior. Funções de ordem superior são
usadas em todo o JavaScript. Também podemos aproveitar esse recurso em nosso próprio código. E com esse exemplo simples, isso que fizemos. Tudo bem, vamos passar
para a próxima seção.
5. Inicio do exercício: criando uma função de ordem mais alta: Ao longo do curso, já
vimos muitos
exemplos de funções de ordem superior quando
falamos sobre o padrão de
retorno de chamada. Como eu disse, todas essas são funções
de ordem superior. Acabamos de ver
alguns outros exemplos
nos últimos tópicos. Então, acho que agora é hora de fazer um exercício em que você crie uma função
de ordem superior. Acho que uma vez que você cria
um por conta própria, isso ajuda a consolidar o poder
de toda essa ideia, que eu acho
importante consolidar, é algo para lembrar
sobre JavaScript. Essa lente do JavaScript, um dos recursos que
o
torna tão poderoso. Aqui está o que eu gostaria que você fizesse. Eu tenho uma variável
declarada sua saudação
e, em seguida, estou chamando uma função. E observe que estou passando
três parâmetros. Uma é uma saudação, porque essa função é criar saudação vai
criar concordar para nós, outra como nome. E então a terceira
é uma função. Então, o que eu gostaria que você
fizesse é criar
a função de criação de saudação e fazer com que ela
use três parâmetros. Se apenas dois parâmetros forem fornecidos, ele simplesmente retornará uma saudação. Mas se um terceiro
parâmetro for fornecido, que é a função
antes de retornar saudação colocando o
termo e o nome juntos, essa função deverá
agir nessa saudação. Portanto, ele deve primeiro
juntar essas duas peças e depois
verificar se a função existe
e se ela atua. Portanto, criar saudação será uma função
de ordem superior. Isso nos dará um
pouco mais de flexibilidade. Além de podermos passar dados
e
fazer com que eles retornem uma saudação
compilada, também
poderemos
passar uma função que nos
fará fazer
coisas diferentes com essa saudação. Agora, esse é um exemplo simples, mas mostra o padrão de uma função de ordem superior
ou o padrão de uso de um retorno de chamada para tornar a função criada
mais flexível e fornecer mais funcionalidade para que você não se repita. Tudo bem, vá em frente
e experimente. E então, quando
estiver pronto, vá para o próximo tópico e abordaremos
isso juntos.
6. Fim do exercício: criando uma função de ordem mais alta: Ok. Como você fez com isso? Eu vou fazer
isso aqui. Isso lhe dá a
chance de comparar o que eu fiz com
o que você fez. Talvez aprenda algumas coisas
adicionais também. Então, acima, vou
prosseguir e configurar Function, create, greeting.
Simplesmente assim. Agora queremos três parâmetros. Vou
chamá-los de turn greeks e depois fn para a função
que pode ser passada. Tudo bem. Agora, vou
declarar variável, e essa será
a saudação inicial, juntando essas duas, o termo e o nome. E parece que
eu não sabia. Não
sei por que coloquei saudação lá
em vez de nome. Aí vamos nós. Então, vai juntar o termo
e o nome. E isso vai colocar
isso nessa variável. Vou usar uma string
de modelo. Então eu uso uma marca invertida
e, em seguida, uso o cifrão e
os colchetes para uma variável. A primeira variável
eu quero incluir o termo
dele e depois quero
um espaço entre elas. Em seguida, incluirei
a próxima variável, que é um nome assim. Então criamos nossa saudação e ela
poderia ser retornada. Se não houver nenhuma função, então nós a
retornaríamos. Então, a maneira como vou fazer isso é verificar se esse valor que é passado
é igual a uma função. Se for, executaremos
a função nela
e retornaremos os resultados. Caso contrário,
terei apenas uma declaração de retorno após a declaração if. Se a instrução if não executada, a instrução return será executada e retornará
essa saudação. Então, vamos ver como fazemos isso. Vou apenas
digitar então. É assim que
descobrimos se algo
é um tipo de função de Fn triplo igual e, em seguida,
dentro da função de aspas. Então, se isso for uma função, essa parte do código
é bem simples. Nós simplesmente queremos retornar a
invocação dessa função. Mas quando a
invocamos, queremos nos cumprimentar. Agora vamos ver como isso funciona. Então, uma função é passada e colocada
nessa variável. Como podemos tratar
funções como valores, desde a primeira classe, podemos
armazená-las em uma variável. Agora que essa função
contém essa variável, podemos invocá-la usando parênteses e passar
um parâmetro aqui. Também podemos verificar
se é uma função
usando o tipo de e que deve ser um ponto e vírgula
. Então, deixe-me corrigir isso. Diz que a parte realmente
não é tão difícil. Às vezes, a
parte mais difícil é
o que você transmite, a funcionalidade que você transmite
como deseja
realizar algo. Tudo bem,
vamos terminar isso. Então, se isso não for executado, se essa parte aqui não for executada, ainda
queremos
retornar uma saudação. E assim, na próxima linha, vou colocar
retorno, saudação. E dessa forma eu posso usar isso com uma função ou
sem uma função. Isso torna tudo
ainda mais flexível para mim. Tudo bem, então
vamos guardar isso. E vamos pular
aqui e
Sue abrirá o console aqui. E eu declarei uma variável
de saudação. Vamos ver o que há nisso agora. Observe que temos um bom
dia Anika. Então esse foi o termo em
nome disso transmitido. E então esses
pontos de exclamação
foram adicionados com
base na função. Eu os passo, deixe-me
voltar para aquela ligação. Então, termo, nome e há uma função vão pegar a saudação
e depois vai Aqui está a
string do modelo novamente. Então, vai pegar o que
acabou porque essa saudação
é passada aqui, é passada para ela, tão rica, que a recebe nessa variável. E então usamos essa variável em uma string de modelo com pontos de
exclamação depois dela. Tudo bem, então isso está
funcionando para nós. Agora, deixe-me fazer um exemplo de criação de avaliação sem
passar uma função. Eu vou embora. Agora
vou usar meu nome aqui. E ainda funciona porque
fizemos esse tipo de verificação. Fazemos isso se a declaração ainda funcionar, se não
passarmos uma função. Agora, só para mostrar
a flexibilidade
dessa função simples de ordem superior, deixe-me fazer outra. Eu vou fazer uma função
diferente aqui. Eu posso digitar corretamente aqui. E agora, para essa função
específica, mais
uma vez, precisamos uma variável para aceitar uma saudação
que é passada para ela. Fazendo uma função de seta novamente, e vou
convertê-la em maiúsculas. Então, algo simples assim. Então, aqui está outro exemplo. Agora, se eu pressionar Enter, obtenho essa sintaxe lá. Você pode ver você? Observe que eu
perdi a vírgula ali mesmo. Então eu vou voltar e vou voltar para cá. Portanto, a mensagem está
mal formada, função de seta. O motivo está mal formado é porque não tínhamos
uma separação por vírgula. Então, uma vez que chegou
lá, também estava considerando isso
como parte disso. E então considere
que o metal se forma. Então, agora, se eu pressionar Return e
obtivermos tudo em letras maiúsculas, basta mostrar um exemplo
do que podemos fazer com essa função agora, muito
flexível. Tudo bem, espero que tenha
sido um bom exercício para você aplicar toda a ideia
de funções de ordem superior. Tudo bem, vamos seguir em frente.
7. Fechamentos: Chegamos ao que
eu acho que é um
dos conceitos mais importantes em JavaScript. Encerramento. Você precisa entender e usar o encerramento para ser um desenvolvedor sério de
JavaScript. Agora, o encerramento é
algo que não é compreendido pelos novos desenvolvedores de
JavaScript. Lembro-me da primeira vez que tive a ideia ou entendi
a ideia de encerramento. Foi um momento de aha para mim. E então eu pude
vê-lo em muitos códigos e usá-lo para resolver problemas
específicos. Então, primeiro eu quero
ver uma definição. Isso vem de Kyle Simpson. Ele afirma que encerramento é
quando uma função é capaz de lembrar um
acesso ao seu escopo lexical, mesmo quando essa
função está sendo executada
fora de seu escopo lexical. Variáveis e funções de seu escopo lexical ainda estão
acessíveis a uma função, mesmo que esse escopo lexical não
seja o ambiente atualmente em
execução. Agora, essas variáveis
e funções são mantidas na memória porque o mecanismo de JavaScript vê que ainda há algo
que pode referenciá-las. Agora, quando esse
tipo de coisa acontece? Quando uma função é executada
fora de seu escopo lexical? Bem, é
muito frequente, mas para saber isso e
explicar melhor, precisamos começar a
ver alguns exemplos. No primeiro exemplo que
quero ver, vou chamar essa
função de saudação atrasada. E vamos ver
como isso funciona. E então vou
explicar o que está acontecendo e qual
encerramento está acontecendo. Portanto, temos uma função
aqui que
podemos passar um nome de
parâmetro. Isso vai ser
uma saudação para nós. Vamos declarar duas variáveis dentro
dessa função. Uma é a saudação. Bom dia, faremos
um espaço depois disso. E então vou usar um saltado para declarar os dois. A outra é uma
variável bombeada para pontuação. E vamos definir isso como um
ponto
de exclamação. Isso é tudo. Então, aqui estão nossas duas variáveis. Agora, tudo o que vamos
adicionar é um setTimeout. Já usamos
muito isso no passado, então essa será uma ótima
maneira de ilustrar o encerramento. Settimeout está tendo uma
função passada para ele. Como sabemos, essa
função não será invocada até que o tempo tenha expirado. E quando o tempo expira, se você se lembrar, a função
é colocada na fila. E então, quando nenhum outro
JavaScript está sendo executado, é adicionado à
pilha e executado. Agora, aqui está o que
vamos registrar. Vamos apenas registrar
a variável grega mais o nome que é
passado em m plus. Tudo bem, agora
vamos definir isso para 5 s. Assim. Tudo bem, agora deixe-me falar sobre
isso em termos de encerramento antes de realmente assistirmos. E deixe-me prosseguir e fazer visualização com atraso de
grau
aqui embaixo para que ele a invoque. Mas em termos de encerramento, então carregamos esse
arquivo JavaScript e a função. E quando começamos a
executar o código, encontramos isso,
adicionamos uma função a ele. E então encontramos
isso que invoca. Essa função é então
colocada na pilha e começa a trabalhar com
o código dentro dela, criando um contexto de execução,
contexto para esse código. Então, essa variável e essa variável
e essa variável são todas acessíveis pelo
código dentro da função. Bem, ele encontra
um tempo limite definido e setTimeout é tratado
pelo navegador, como sabemos. E então o navegador começa a
contar os 5 s. Bem, essa função
termina e está concluída. Antes que essa contagem
regressiva termine. Está pronto e é
removido da pilha. Então, o que acontece com
essas variáveis? Eles ainda estão acessíveis
por essa função? Como essa função ainda não foi adicionada
à fila, ainda estamos
contando os 5 s. Em seguida, ela é adicionada à fila. E então, quando há espaço, ele é adicionado à pilha. E então ele começa a executar
o código dentro dele. Então, aqui está o código dentro dele. E agora tem que pegar saudação, nome e punk, mas essa função já
foi removida da pilha. Então, o que acontece? Bem, é aí que
entra o
encerramento , porque o
mecanismo JavaScript sabe que essa função ainda
tem uma referência a essas variáveis que fazem
parte de seu escopo lexical. Léxico onde está escrito. E esse é o escopo aqui. Então, ele ainda tem acesso a isso. Eles são mantidos na memória. Mesmo que essa função tenha terminado de ser executada e
removida da pilha, essas variáveis não são
limpas quando obtidas na memória. Então, essa função
é capaz de acessá-los porque eles faziam parte
de seu escopo lexical. O mecanismo de Javascript sabe o suficiente para mantê-los por perto e
poder usá-los. Então isso é encerramento. O fechamento é criado em torno dessas variáveis para que essa função posteriormente ainda
possa acessá-las. Um recurso muito poderoso,
se você pensar bem, podemos
executar e
finalizar algo e ainda ter
acesso às variáveis. Muito poderoso. Ok, então
eu quero salvar isso. Então eu vou
reduzir isso um pouco. Vamos
abrir o console. Aí está meu retorno inicial. Eu não quero colocar
um nome lá. Por que eu não coloquei
um nome em uma ligação tão boa, Steve, desse jeito. Tudo bem, agora vamos salvá-lo. A função desapareceu. É contagem regressiva, contagem
regressiva, contagem regressiva. 5 s acabou. Temos um bom dia, Steve, bem
como acesso a todas essas variáveis
por causa do fechamento. Então, à medida que permanecemos ou como afirmei, a função é
removida da pilha. Mas, apesar disso, as variáveis ainda
são retidas na memória porque o motor ou outra
coisa pode
estar fazendo referência a elas. Portanto, podem ser
variáveis que podem ser uma função que essa
função chama. Todos eles são mantidos
na memória para que seu acesso, desde que
faça parte do escopo lexical, ele tenha acesso a eles e não seja limpo pelo mecanismo de
JavaScript. Tudo bem, vamos dar
outro exemplo. Vou acessar o arquivo
HTML aqui e vou
adicionar dois botões. E eu quero que o primeiro botão
tenha um ID de botão de um. Então, estou usando o
atalho para fazer isso. M, É um plug-in para o
Visual Studio Code. Quando eu pressiono tab, ele cria o botão para mim
com o ID correto do botão. E eu vou dar um
nome ao botão. Clique em Eu assim. Ok, agora vamos
colocar outro botão aqui. E eu quero que esse também tenha um ID, mas esse será o BTM para fazer, clique em mim também, assim. Então, esses são os dois botões
que adicionamos. Guarde isso. Vamos ver se eles
estão aparecendo. Sim, eles estão aqui. E então recebemos a mensagem,
esse código ainda está funcionando. Então, se virmos aqui, vou comentar
isso por apenas um minuto enquanto
fazemos outra coisa. Então, o que eu quero fazer é criar
uma função de inicialização. Essa é uma função que
executaremos quando esta página for carregada e inicializará
algumas coisas, principalmente os ouvintes do evento. Então, vou chamar isso de nicho. Ela mente. E então vou colocar
algumas variáveis aqui. Talvez você possa ter
uma ideia do que estou fazendo aqui com o Closure. Vou
configurar duas variáveis. E essas duas variáveis
ainda estarão acessíveis mesmo depois que essa função de inicialização
estiver completamente concluída. Portanto, a função
de inicialização será executada primeiro. Isso vai configurar os ouvintes do evento que
estou fazendo agora. Vamos ver. Aliás, uma é uma das
que eu quero fazer. Adicione o ouvinte do evento. E vamos usar o evento de
clique para configurá-los e, em seguida,
será concluído. Mas mesmo com a conclusão, ainda
teremos acesso a essas variáveis e veremos
como podemos lidar com isso. Então, uma das coisas que
vamos fazer é C e T.
Vamos apenas incrementar a primeira variável lá e depois
logar no console C e T. é o
que faremos
nesta primeira, dessa forma. E deixe-me ir em frente e
ponto e vírgula ali, e
ponto e vírgula ali. E eu vou copiar este e basicamente fazer algo semelhante
para o próximo aqui embaixo. Mas desta vez
vamos fazer bt e dois, e desta vez vamos incrementar
a contagem, mas vamos fazer com
o valor do incremento. Então, faremos
incrementos mais iguais como esse. Em seguida, registraremos a
contagem no console novamente. Tudo bem, nós temos essa configuração. Agora, quando a página carregar, vou chamar initialize. Então, isso vai ser executado e será
removido da pilha. No entanto, essas variáveis
serão retidas na memória
porque são referenciadas por essas
funções aqui, essas funções anônimas que fazem parte do ouvinte de eventos. Então, quem sabe quanto tempo
vai demorar depois que essa função for
concluída, antes desses botões
ou até mesmo de ser clicada. Realmente não importa
quanto tempo possam levar anos. Enquanto essa
página permanecer ativa, ela os manterá na memória e terá acesso a eles. Tudo bem, então vamos guardar isso. E agora, obviamente, essa função
inicializada
já foi concluída. Vamos fazer o Click Me e
entraremos no console. Vamos clicar neste aqui. Ele vai se lembrar desse número que foi
incrementado aqui? Isso acontece. Isso adiciona mais dois a ele. E eu clico aqui quando
ele adiciona um a ele. Então, duas funções diferentes, mas elas estão abordando
o mesmo escopo lexical. Então, eles estão abordando
a mesma variável. E por causa do fechamento, essas variáveis são mantidas. Eles são acessados por
ambas as funções. Você pode ter uma ideia. Agora, o poder que o fechamento
pode fornecer em JavaScript é realmente um
recurso importante do JavaScript. Fornecemos os
primeiros exemplos de encerramento usando setTimeout e
também usando addEventListener. Bem, o que eu quero fazer
a seguir no próximo tópico é
usar uma função de ordem superior para mostrar também a aplicação
do fechamento. Então, vamos passar
para o próximo tópico.
8. Usando o fechamento com funções retornadas: Quando falamos sobre funções de
ordem superior, uma coisa que tornou uma
função de ordem superior é se ela voltou a funcionar. Combinando esse
recurso com o fechamento, temos uma construção bastante
poderosa. Porque, de repente, podemos retornar uma função de uma função. E essa função retornada
terá acesso ao escopo da função original,
qualquer configuração variável. E ele funciona declarado. Teremos acesso
a todos eles. E um dos benefícios disso
é que não precisávamos colocar nenhuma
dessas variáveis em funções
no escopo global
para torná-las acessíveis. Em certo sentido, eles são privados. Eles só podem ser acessados
por coisas em seu escopo. E a função de retorno
pode continuar atuando sobre eles e usando-os. Vejamos um exemplo. Tudo bem, agora observe o número de coisas que declaramos aqui. Temos uma variável, temos três funções
e, em seguida, temos essa
função que é criada pela composição das três
funções anteriores a ela. Então, temos uma boa parte do
que está declarado aqui e está no espaço global. Ao usar essa ideia da qual
acabamos de falar, vamos colocar tudo dentro de
uma função e fazer com que
ela retorne uma função
que fará isso. mesma coisa. Tudo bem? Então, vamos chamar isso, vamos chamá-la de função Get
por uma questão de simplicidade. E eu vou pegar
isso e cortar aquilo. E então vamos prosseguir
e recuar tudo isso. Aqui embaixo. Adicione a cinta encaracolada de fechamento. Então, essa é a nossa função. Temos essa configuração, mas agora precisamos
retornar uma função. Portanto, podemos fazer isso
simplesmente substituindo essa
peça aqui pela devolução. E ele retornará
essa função aqui. Agora, atribua isso para
multiplicar por cinco e assim por diante. Podemos declarar essa variável. E podemos defini-la como igual a essa função que
acabamos de criar a função Get. Então, quando essa
função for concluída, a função get for concluída, ela retornará uma função
, que será colocada e
multiplicada por cinco e exibida. Tudo bem, agora essa função aqui, mesmo que a função acima esteja completamente concluída, ela foi removida da pilha. Ela terá acesso
a isso e isso e isso e a
ninguém que as variáveis possam ter acesso a tudo o
que
estará disponível para ela. E então, se mudarmos
a assinatura disso. Então, se estamos apenas
passando um número, digamos e dois. E então, aqui embaixo, usamos número um deste
declarado anteriormente. Agora, isso sempre vai
se multiplicar por cinco
e outra coisa, o que for passado. Então, isso fará com que seja
multiplicado por cinco e uma tela, que
será retornada aqui. Agora estamos passando
apenas um número como esse. Agora vamos salvar
isso. E vamos dar uma olhada nisso. Abra o console aqui. E devemos ter acesso para multiplicá-lo por cinco e Display. E vamos passar em seis. E isso nos devolve 30 formatos que colocam a
pontuação depois de qualquer forma, ele faz todas as
outras coisas que faziam parte dessa função. Essa função aqui, a função
get, função, então ela tem acesso
a todas elas. Agora, outra coisa que
poderíamos
fazer para melhorar isso é usar numum aqui em cima. Podemos nos livrar
da declaração aqui e
tê-la apenas como parâmetro. Agora, quando criamos a função multiplicar por cinco
e exibir, passamos cinco. Mas também podemos
criar multiplicado por, vamos fazer dez e exibir. De repente, isso fica
muito mais flexível. Acabamos de passar em dez minutos lá. Agora temos duas funções que foram
criadas a partir disso. E cada um
deles tem acesso a tudo o que faz parte do escopo lexical dessa
função que é retornada. Então se torna, se torna
muito poderoso dessa forma. Então, vamos dar uma olhada neles. Vamos fazer nossa multiplicação por cinco. Vamos fazer sete desta vez. Então, isso ainda está funcionando para nós. E agora também temos
uma multiplicação por dez. Vamos fazer sete
nesta também. Então,
agora temos duas funções que têm acesso a
tudo o que está dentro disso. O escopo da
função get, mesmo que essa função não
esteja mais em execução. O mecanismo de JavaScript
é inteligente o suficiente para saber que pode haver algo que
ainda faz referência a ele, então
encerra isso. Esses são mantidos na memória. E por causa do fechamento, podemos acessá-los. Agora, deixe-me mostrar outra
coisa que podemos fazer assim como estamos lidando com
funções de ordem superior aqui, compartimento. Deixe-me
ir até o console. Vou chamar a função get. E eu vou passar
em 20 desta vez. Agora, o que isso
vai retornar? Bem, ele retornará uma
função, como podemos ver aqui. Agora, como isso está
retornando uma função, eu poderia fazer algo assim. Como a função
está sendo retornada, eu poderia invocá-la imediatamente. O próximo conjunto de
parênteses invocará a função que está
sendo retornada. E eu vou passar em cinco, e isso deve ser igual a 100. Agora temos uma função. Se usarmos apenas a função de lacuna dessa forma, temos uma
função em que podemos multiplicar quaisquer dois números
e exibi-los. Agora, o que estou
tentando mostrar aqui é apenas a flexibilidade por causa da função de ordem superior, por causa do fechamento
que foi criado. E é por isso que eu disse que
é uma construção poderosa
em JavaScript, é uma construção poderosa
em JavaScript a qual precisamos estar familiarizados com a qual precisamos estar familiarizados e capazes de usar. Tudo bem, vamos
passar para o próximo tópico.
9. Características importantes de fechamento: Agora, eu sei que tenho
insistido muito nisso, mas fechamentos são importantes. Quero usar este tópico para
apontar duas características dos fechamentos que
os tornam importantes. Agora, essas não são as únicas
características dos fechamentos. Mas dois que eu quero
que você entenda. A primeira característica é que os
fechamentos podem nos ajudar a usar
com eficiência tarefas que consomem muita memória
ou CPU. Agora, deixe-me dar um
exemplo disso. Então, aqui está nosso código que
estávamos usando antes. E digamos que, como
parte desse código, temos um processo que recupera dados de um banco de dados ou de uma API em algum site. E o que obtemos disso
quando obtemos essa enorme variedade. Agora vou
representar essa enorme matriz apenas com uma pequena matriz. Mas pense nisso como uma taxa enorme. Esses são os dados que
retornam da
API do site usando algum tipo de comando
assíncrono. Falaremos sobre coisas
assíncronas mais tarde. Mas temos que lidar
com isso de forma assíncrona porque leva muito
tempo para voltar. Mas quando finalmente
volta, obtemos essa matriz de números. Tudo bem? E então estamos
mudando isso para um índice. E, basicamente, o que
estamos fazendo é pegar da enorme matriz o número que
vamos escolher. Está bem? Agora, deixe-me enfatizar novamente
que, ao recuperar esses dados, leva algum tempo para eles
irem para
o banco de dados ou para o site, obtê-los
e trazê-los de volta. Portanto, temos que lidar com
isso de forma assíncrona. Agora pense se cada vez que quiséssemos multiplicar
números, precisávamos fazer essa tarefa
intensiva. Tivemos que sair
e obter esses dados. Cada vez que fazíamos
isso, levávamos segundos
ou o que quer que fosse, mesmo que fosse um pequeno
número de segundos, até milissegundos, esses podem se somar cada vez que
saímos e fazemos isso. Portanto, pode ser intensivo. Bem, se nossa função, função sai
e a recebe uma vez, e então a temos
armazenada nessa variável. E então, por meio do fechamento, podemos continuar a
acessá-lo usando a tela Multiplicar por cinco e depois
multiplicar por dez para que cada vez que quisermos multiplicar por cinco, não
precisemos
sair e obtenha esses dados. Cada vez que chamamos essa função. É apenas uma referência ao que
já temos armazenado na memória. Já fez o
processo para obtê-lo. Tudo bem, é assim que ele
pode nos ajudar a usar com eficiência consomem muita
CPU, tempo
ou tarefas que consomem muita
CPU, tempo
ou memória. Ao usar o Closure, podemos
disponibilizá-lo continuamente para nós. Tudo bem, agora, o
segundo recurso, recurso sobre o qual quero falar,
chamamos de encapsulamento. Agora. Para entender o que é
um encapsulamento,
deixe-me expandir essa ideia. Chegamos onde
temos essa enorme variedade. Digamos que
isso seja algo, essa matriz é algo que não
queremos que seja alterado. Seja como for, em qualquer
parte do programa. Há apenas um lugar em
que queremos poder mudá-lo, e em nenhum outro lugar do programa isso
deveria acontecer? Bem, podemos configurar uma
função, algo assim, onde passamos um
novo número e, em seguida, esse novo número é adicionado
à matriz e essa é a
única maneira de atualizá-lo. Está bem? Então, nós apenas fazemos um empurrão
aqui com um novo número. Portanto, não queremos que as pessoas
possam acessar matriz e
adicionar números a ela. Na verdade, talvez, toda vez que alguém
adiciona um número a ele, queiramos verificá-lo de alguma forma para garantir que ele atenda a
alguns critérios. Portanto, podemos ter uma declaração
if aqui. Se num for maior que 100, talvez seja tudo o que estamos aceitando
ou algo parecido. Então vamos seguir em frente
e seguir em frente. Portanto, controlamos a
adição de novos números a essa matriz usando
essa função. Então, a única maneira de as pessoas manipularem a matriz
é com essa função. Eles têm que passar por isso. Agora, agora
estamos retornando às funções que obviamente não
são permitidas. Uma maneira de fazer isso, se
tivermos duas funções, queremos retornar de
algo assim, é retornar um objeto. Então, se mudarmos
essa função também, atualize a matriz assim. E mudamos essa para
criar uma função como essa. Poderíamos então devolver um objeto. E nós atualizaríamos a matriz e criaríamos diversão. Ambos fariam
parte desse objeto. Então, quando
chamamos essa função, o retorno é um objeto. Então, obtenha a função. O que recebemos de volta é um objeto. E então podemos usar esse objeto. Podemos fazer OBJ para
atualizar a matriz para chamar essa função ou OBJ dot create fund para
chamar essa função. De qualquer forma, é assim que faríamos isso em vez de
fazer duas funções de retorno. Mas o que quero
dizer é que agora
criamos uma função de que essa é a única maneira de
alterar essa matriz. Então, incluímos essa
matriz dentro de uma função. Nós o encapsulamos. Então, isso é encapsulamento, ele o protege de
uma única maneira, uma maneira de alterá-lo e
podemos verificar se isso é alterado. E, na verdade, essas outras funções também
estão encapsuladas. Eles não estão disponíveis
fora dessa função. A única maneira de
usá-los é com isso aqui. Isso tem acesso a eles, mas nada mais
tem acesso a eles. Então, eles estão encapsulados. O ensaio, a ideia
de encapsulamento. Ambos os recursos são importantes quando se
trata de fechamento. Tudo bem, vamos
passar para o próximo tópico.
10. Início do exercício: fechamento 1: Tudo bem, é hora de
um exercício mais aprofundado. Agora vou
apresentar o problema para você neste primeiro vídeo
e, em seguida, no próximo tópico,
abordaremos a solução. Agora, esse problema específico é algo que você
pode ver na internet. É um problema muitas vezes apresentado para ilustrar o encerramento. Talvez também faça parte da
entrevista em JavaScript. Portanto, é muito prático
no sentido de que é o tipo de problema
que as pessoas apresentam para ver se você
entende o encerramento. Então, vamos dar uma
olhada no que é isso. Tudo bem, então eu tenho uma matriz
aqui e uma taxa de alunos, e eles são apenas nomes, primeiros nomes nessa matriz. Total de cinco alunos.
Isso é tudo o que existe. Então, temos um for-loop e estamos
percorrendo essa matriz. Declaramos a variável. Percorremos o circuito enquanto ele é menor do que o
comprimento dessa matriz. E então incrementamos aqui. E então, dentro desse
loop, temos um tempo limite definido. E essa é a função
que é
colocada na fila quando o
tempo expira. Portanto, setTimeout é gerenciado
pelo navegador, a API da web. E quando esses 2 s expiram
, essa função
aqui é colocada na fila e no loop de eventos, assim que tem espaço para ela,
ela a adiciona à pilha e
essa função é executada. Ok, então conhecemos todo
esse processo. Agora vamos ver quais são os resultados disso. Estamos analisando isso. O que vai
exibir o log do console. Então, se eu abrir
o console aqui, basicamente obtenho cinco declarações
indefinidas. Isso é tudo que eu tenho no registro. Então, quando ele está logando
no console, ele não consegue encontrar nada
na matriz e simplesmente
imprime indefinido. Então, isso tem duas partes. Este exercício tem duas partes. Primeiro, quero que você
pense e seja capaz explicar por que
existem cinco indefinidos Por que isso acontece? E explique isso em termos de coisas que aprendemos
sobre o escopo. A segunda parte é então
usar o fechamento para resolver esse problema para
que isso não aconteça. Para que realmente sejamos
registrados no console, os nomes que estão
aqui na matriz. Então, duas partes desse exercício. Agora, direi existe uma maneira simples de
resolver esse problema, mas quero que você use o
fechamento para resolvê-lo. Falaremos sobre a maneira simples no final da solução, porque acho importante
entender isso também. tanto o fechamento quanto
esse outro conceito importante
entender tanto o fechamento quanto
esse outro conceito
. Então, dedique algum tempo. Quando estiver pronto, passe para o próximo tópico e
analisaremos essa solução.
11. Fim do exercício: fechamento 1: Como você se saiu com isso? Espero que você consiga
resolver isso. Vamos primeiro falar sobre por que estamos obtendo
os cinco indefinidos. Vamos fazer isso primeiro. Portanto, observe que tudo aqui não
é criado
dentro de uma função, então estará
no escopo global. Então, isso está no escopo global. Essa declaração de carros, o olho, está no escopo global. Tudo bem, então isso é
colocado no escopo global. Em seguida, iniciamos nosso
primeiro setTimeout. Isso é feito pelo navegador.
Comece a contar em dois segundos. O loop for continua funcionando. Então, basicamente, cinco
desses cinco setTime se esgotam muito rápido após o outro
e estão prontos para 2 s.
Tudo bem? Agora, quando
chegarmos à última,
a última iteração disso
para o loop i é incrementada. E então eu, naquele
momento, me torno cinco. E eu estou no escopo global. Então, uma vez que esses 2 s são
feitos para o primeiro, essa função é
colocada na fila. Ele é captado
pelo loop de eventos e colocado na pilha. Ele invoca. Essa linha aqui é executada. Alunos cinco é indefinido. Temos 012345 indefinido. É por isso que estamos
recebendo o indefinido. Então, o que queremos fazer
é configurar o encerramento para fechar uma variável que
pode ser usada aqui. E não usará
a variável global I, que é alterada cada vez fazemos iterações no for-loop. Tudo bem? E ao configurar uma função, definimos um novo escopo. E assim, o fechamento
é tratado para esse escopo e para a variável
que usamos dentro dele. Então, vamos seguir em frente e ver
como podemos fazer isso. Há algumas
maneiras de fazer isso. Mas na primeira, vou
criar uma função aqui. E eu vou fazer uma declaração de
função desta vez apenas para mantê-la mais curta. Vou
chamá-lo de show learner. E então vamos
continuar e cortar isso. E vamos colar isso
dentro dessa função. Então, como
configuramos uma nova função, definimos um novo escopo. Agora podemos colocar uma
variável dentro dela. Então, deixe o aluno ser igual e eu vou
definir isso para os alunos. E então o índice I. Então, vamos atribuir um dos nomes a
essa variável do aluno. E é exatamente isso que
vamos mostrar aqui. E assim, por causa do fechamento, quando essa função for acionada, ela terá acesso
a essa variável. E cada vez que essa
função for invocada, ela criará uma
nova variável para o novo escopo
criado. Então, aqui embaixo, eu precisaria
colocar show learner. Portanto, é invocado toda vez
por meio desse loop for. Agora, quando entramos expressões de
função
imediatamente invocadas, há uma
maneira mais simples de fazer isso, que veremos naquele
momento. Mas, por enquanto, estou apenas
invocando a função aqui. Ele chama isso, configura uma variável dentro do escopo
dessa função. Essa função porque faz
referência a essa variável. E por causa do fechamento, essa variável será retida na memória para que ela
tenha acesso a ela. E isso deve resolver
o problema para nós. Então, se eu disser isso depois de 2 s, todos os nomes serão exibidos. Tudo bem, então essa é uma abordagem. Vou copiar isso.
Então, eu tenho uma versão de cada um deles no
código que você pode ver. Vou apenas
comentar esse aqui. Então, outra abordagem
teria sido definir uma variável idx, talvez para índice, e
simplesmente defini-la como I. Ok, então essa variável
agora faz parte desse escopo. Então, isso vai fazer
a mesma coisa. A única diferença
está aqui embaixo. Em vez de i, usamos idx para referenciar a
posição na matriz. E isso também
funcionará bem para nós. Se eu salvar isso, saímos daqui após 2 s, podemos ver os nomes sendo exibidos. Tudo bem, agora eu mencionei que também há uma solução simples
para isso. Então, deixe-me mostrar o
que é essa solução simples. Deixe-me copiar isso. Então, essas duas primeiras soluções, Usando mais perto, deixe-me
fazer um comentário lá. Usando o fechamento. Comente isso. Então, não estamos mais lidando
com isso. A segunda é simplesmente
usar a propriedade de LET. Agora, se você se lembra
de uma das diferenças sobre as
quais falamos com let e
const em vez de var, é que os cons latinos
têm escopo de bloco. O que significa escopo bloqueado? No caso desse for-loop? Vou remover
isso muito rápido e deixar eu me livrar disso. Vamos apenas colocá-lo de
volta do jeito que era. E então eu quero usar I
aqui para referenciá-los. Agora, voltando à
ideia do escopo do bloco. O que significa osciloscópio de caminhada? Bem, o escopo está aqui. Então, como o escopo do bloco
é definido, se mudarmos isso para
lat em vez de var, escopo já está
dentro disso. E essa função
ainda fará referência
a ela por meio do fechamento. Portanto, a variável I
será mantida na memória. E cada vez que passa pelo loop, basicamente ele está declarando
uma nova variável i. Por causa do escopo do bloco
que obtemos com let. Tudo bem, então cada uma
dessas funções terá
uma referência a esse I. E isso resolverá
o problema para nós. Está bem? Então, isso resolve o problema usando um recurso de let que
às vezes esquecemos. Esquecemos que o escopo do bloco pode fazer esse tipo
de coisa por nós. Mas deixe-me mostrar
que vou guardar isso. Salte novamente após 2 s. Mesmos resultados, mesmos resultados. Agora acho que
mencionei quando estava falando sobre que essa solução
realmente não usa quase nada. Bem, ele usa fecho. Ainda estamos fechando
por causa de uma variável. Agora, os estilos de função
fazem referência a ele. Mas a razão pela qual isso
funciona e var não é porque lat tem esse escopo de
bloco aqui. Var não tem escopo de bloco
e, portanto, foi direcionado
para o contexto global. Então essa é outra solução. Agora, se você não conseguiu
chegar a essa solução,
espero que pelo menos
você a entenda. Espero que você veja como eles usam o fechamento para
resolver o problema para nós. E eu gostaria que você
fizesse mais um exercício, então faremos mais um em seguida. Vamos seguir em frente.
12. Início do exercício: fechamento 2: Vou pedir que você faça um
segundo exercício sobre fechamentos. Como você pode ver, adicionei três botões
a essa página HTML. E esse exercício envolve
esses três botões. Deixe-me ir para
o arquivo de código. Eu tenho uma descrição do que
eu gostaria que você fizesse lá. E esses são os mesmos
arquivos de código que você usará
para o exercício. Primeiro, aqui no topo, criei
três constantes que têm os botões que
criei em uma página HTML. Esses três botões aqui, suas referências,
esses três botões, eu
os criei. Você pode usá-los ou
criar o seu próprio. Acabei de adicionar isso
, caso alguns não tenham certeza como selecionar esses
botões do DOM. Agora, aqui está o que eu
gostaria que você fizesse. Cada vez que um desses
botões é clicado, ele deve exibir dois números. O primeiro número que ele
deve exibir é a quantidade de vezes que
o botão foi clicado. E então um segundo número é o valor cumulativo
dos três botões. Então, deveria dizer
algo assim. Fui clicado três vezes. Todos os três botões foram clicados dez vezes,
algo assim. E é importante que você use o fechamento para que isso aconteça. Agora, fique atento. Existem centenas de maneiras de
resolver esse problema. Existem centenas de maneiras fora do fechamento de resolvê-lo, mas existem centenas de maneiras de
usar o Closure para resolvê-lo. Portanto, sua solução provavelmente será um pouco
diferente da minha. A questão é que eu quero que
você use o fechamento. Quero que você pratique
fazer isso e pensar em seu código com encerramento como uma
ferramenta para resolver esses problemas. Então é assim que eu gostaria que
você abordasse isso. Tudo bem, vá em frente e
espere um pouco. Quando estiver pronto para seguir
em frente e ver a solução, vá para o próximo tópico.
13. Fim do exercício: fechamento 2: Tudo bem, vamos passar por isso. Agora tenho certeza de que minha solução será
um pouco diferente da sua. Eu suspeito que o que muitos de vocês fizeram foi criar
uma função externa. Você declara três
variáveis, quatro variáveis, na verdade uma para a conta
total e
talvez uma variável para
cada contagem de botões. Em seguida, você os
incrementaria
nos horários apropriados e exibiria a mensagem apropriada. Vou adotar uma abordagem
um
pouco diferente para resolver essa solução. Eu queria ter certeza de
usar o princípio DRY. Eu não queria repetir coisas que eu não precisava repetir. Eu vou ter
uma única função que será exibida. Eu vou ter uma
única construção. Isso adicionará um
ouvinte de eventos a cada um deles. E, basicamente,
eliminei o uso de qualquer declaração de IF para fazer o que
fiz por causa do fechamento. Como tenho certeza de que sua solução também
usa o fechamento. Então, vamos
começar para que eu possa te
mostrar minha solução. Podemos aprender com isso juntos. Então, vou primeiro configurar uma função de inicialização
que será
a função externa que estabelecerá tudo isso. E então eu vou querer invocar
isso para começar. Então, vou colocar isso aqui embaixo. Impressões duplas para indicar que estamos invocando
essa função. Agora, o que vou fazer com essas declarações aqui é
configurar uma matriz, apenas acessando os botões. E essa matriz
conterá cada uma
dessas declarações. Agora, a razão pela qual estou fazendo
isso é que vou
declarar os
ouvintes avançados com um loop. Então, eu quero colocá-los em uma matriz apenas para tornar
isso mais simples para mim. Porque então eu posso simplesmente
percorrer essa matriz, pegar cada item, cada elemento, adicionar o ouvinte de eventos e,
em seguida, estou pronto para continuar. Então, aqui está minha matriz. Agora preciso configurar
outra variável. Essa será
a contagem total. Isso precisa ser parte disso em todo o escopo
dessa função geral. Porque ele precisará
ser incrementado pelos
três botões. Então, inicialmente vou
definir isso como zero. Tudo bem, agora, enquanto eu estava
pensando sobre isso, imaginei, bem, cada um
desses botões exibirá a mesma mensagem. Então, eu realmente deveria ter
uma função que possa exibir essa mensagem em cada um
desses botões para incrementar a variável de contagem
total. Então eu deveria ter uma
função que também faça isso. Então eu pensei, bem,
eu posso colocar essas coisas em uma única função. Então, vou configurar isso agora. Incremento e exibição. Se eu puder digitar contadores, é assim
que
vou chamá-lo. Lá dentro,
posso
incrementar imediatamente a variável de
contagem total. E então eu posso registrar
a mensagem no console. E vou usar uma string de modelo apenas para tornar
isso um pouco mais fácil. E eu vou copiar, vou copiar exatamente a mesma frase aqui embaixo. Isso é o que eu
queria mostrar de qualquer maneira, então vou copiar isso. Agora, no lugar da contagem
total, esta aqui. Preciso colocar a contagem total
variável. E o que eu vou colocar aqui? Bem, acho que o que vou
fazer é passar
a contagem de cada botão. E então eu posso substituir isso
por aquele passado invariável. Já que isso é um parâmetro. O escopo dessa
variável está aqui, enquanto o escopo da
contagem total é tudo isso. Então, quando eu criar os
ouvintes do evento aqui embaixo, ele poderá
incrementar a conta. E essa função
aqui também terá acesso à contagem total
até o fechamento. Então, ele estará disponível. Tudo bem, agora
vamos continuar e incrementar os ouvintes do evento. E como eu disse, eu configurei uma matriz para que eu possa
fazer isso em um loop. Então, percorra isso. E isso me permite fazer
o mesmo código apenas uma vez. Porque configurar
esses ouvintes de eventos seria o mesmo código. Agora, aqui está o que eu quero
fazer dentro disso para loop. Vou declarar uma variável
e vou usar lat. Então, o escopo disso
será esse bloco. E eu vou defini-lo para zero. Portanto, essa é uma variável
diferente dessa porque elas
têm um escopo diferente. Tudo bem? Eles não estão em
conflito um com outro, embora
tenham o mesmo nome. E eu estou configurando isso porque no EventListener eu
vou configurar uma função. Isso então terá acesso
a essa variável e nós
incrementaremos essa variável e a
passaremos para aqui. Tudo bem. Então, cada vez que isso for chamado, ele terá uma variável
diferente ou possivelmente uma
variável diferente transmitida. E por causa do encerramento, poderei
acompanhar a contagem total. Eu poderei acompanhar
a contagem individual. Então, agora vamos
configurar esses ouvintes de eventos. Portanto, o BTN, usando o loop for, btn agora contém cada um desses elementos DOM à medida que ele
itera nessa matriz. Então, BTN, adicione ouvinte de eventos. Então, queremos usar
os eventos de clique, e aqui está minha função
anônima. Agora, o que vamos fazer dentro dessa função anônima? Bem, primeiro vamos
incrementar essa variável aqui. Essa função
terá acesso a essa variável por meio do fechamento. Então, para acompanhar
as contas. Depois de incrementarmos,
continuaremos
ligando para os contadores de exibição de incremento. E vamos
passar essa variável. Essa variável aqui que foi incrementada será
passada para aqui
e, em seguida, será
exibida aqui. E essa variável
que faz parte
desse escopo simplesmente será incrementada toda vez que
a função for chamada. E como eu percorri todos os elementos da matriz, todos esses botões terão
o mesmo ouvinte de eventos. Então, todos nós vamos
chamar essa mesma função. Como esse é um loop, essa será uma
variável diferente a cada vez que
passar por esse loop. E depois as funções
para cada ouvinte de eventos. Bem, eu tenho acesso a
ele por causa do fechamento. Tudo bem, vamos
ver como isso funciona para nós. Vou
guardar isso. E vamos voltar para cá. E digamos que eu queira exibir o console para que possamos ver
as contagens que estamos recebendo. Então, deixe-me rolar
para baixo até os botões aparecerem. E se clicarmos no botão
um, o que obteremos? Uma vez, todos os três botões
foram clicados uma vez. Deixe-me clicar
novamente. Duas vezes. Vou clicar em todos os três botões duas vezes. Agora marcou um botão para
uma vez, três vezes. Vamos para o botão três. Uma vez, quatro vezes, aperte o
botão para novamente, duas vezes, cinco vezes. Parece que está funcionando
duas vezes, seis vezes. Tudo bem, então um pequeno
exercício divertido usando o fechamento. Então, espero que este exercício tenha
sido muito educativo. Você não só teve a
chance
de tentar descobrir isso sozinho. Mas talvez você também possa aprender algo com a
abordagem que adotei. Porque, como eu disse, provavelmente
há 100 maneiras diferentes de
resolver esse problema. Tudo bem, vamos
passar para o próximo tópico.
14. Expressões de função imediatamente anuladas: Expressões de
função imediatamente
invocadas são um
padrão importante em JavaScript. Eu mencionei isso
brevemente durante
alguns dos tópicos anteriores. Bem, agora vamos
analisar isso com mais detalhes. Imediatamente. As expressões
da função Invoke são chamadas de IFIS no mundo do
JavaScript. Essa é a maneira como você
pronuncia o IIFE que você vê
no final da linha do título. Duvidoso. E se ele está simplesmente definindo uma função e, em seguida,
invocando-a imediatamente, não
esperamos para ligar mais tarde. É definido e em
massa ao mesmo tempo. Vamos dar uma olhada em um
exemplo simples e, em seguida,
falarei sobre alguns
dos motivos que usamos. Se ele estiver bem, vou
criar uma
função muito simples aqui. Basicamente, vou adicionar dois números e
retorná-los também. Então, vamos voltar,
vamos fazer cinco mais cinco. Agora, se salvarmos isso, eu vou pular aqui e dar uma
olhada no console. Se observarmos a variável soma, o que ela contém, vemos que
ela contém a função. Agora, se quisermos invocar isso
, temos que adicionar as purinas. Agora, e se
pudéssemos definir isso? E então basta colocar os parênteses
duplos no final aqui para que estejamos definindo a função e, em seguida,
invocando-a ao mesmo tempo. Isso significaria que é
imediatamente invocado. E essa é uma expressão de
função. Portanto, uma expressão de
função imediatamente invocada. Então, vamos tentar isso. colocar
as duas
aspas depois disso. Agora, o que vai estar
na variável soma? Será a função? Saiba, será o valor que
será retornado se for
imediatamente invocado. Então, vamos salvar isso. E então vamos dar
uma olhada em alguns. Agora, ele contém a resposta ou o valor de retorno dessa função porque
foi imediatamente invocado. Então, esta aqui é uma expressão de
função
imediatamente invocada. Não funciona para uma declaração de
função. Não podemos fazer esse tipo de coisa. Vamos ver o retorno. Vamos fazer algo assim. Quero que você
mostre o que acontece se
estabelecermos uma declaração. Então, se eu salvar esse erro de sintaxe
não detectado, um token
inesperado na linha nove. Então, por que nove não gosta disso? Não sabe o que
estamos fazendo aqui. Portanto, isso não pode ser feito com
uma declaração de função, tem que ser uma expressão de função. Então, sempre que estamos
invocando algo imediatamente é uma expressão de função. Agora, deixe-me mostrar tipo de coisa que pode
ser feita com isso. Vou fazer uma soma de dez e vou definir isso como
igual a uma função. E teremos um parâmetro para um
número que será transmitido. E então,
aqui, vamos
declarar uma variável e defini-la como igual a
dez, desse jeito. E então
retornaremos num mais um. É por isso que estamos
chamando isso de dez. Agora, o que acontece se imediatamente
invocarmos essas pegadas em torno disso? Salve isso. Vamos dar uma olhada em cerca de dez. Nan está nos dizendo
que não é um número. O que está nos dizendo
que, por um tempo,
não repassamos um valor para isso. E então está tentando adicionar
indefinido a dez, diz NaN. Então, vamos passar um valor
e vamos fazer cinco. Guarde isso. Agora temos 15 com algum tempo. Agora, quero que você saiba de algo com essa variável
que acabei de colocar aqui. Não há nada que possa alterar essa variável
depois de definida. São dez. E não é só porque
usei uma constante definida,
obviamente, um policial que
impede que ela
seja reatribuída
receberá um erro de sintaxe. Mas também é porque está
contido nessa função. O fato de estar definido
nessa função significa que
não temos acesso a ela, a nenhum outro código ou que
podemos até mesmo vestir essa variável porque
ela está dentro da função. Tudo bem? Então, a razão pela qual mostro
isso é que isso ajuda a ilustrar os casos de uso da expressão de
função
imediatamente invocada na verdade,
existem duas delas. Vou apenas
inseri-los aqui. Casos de uso que eu
acho importantes. Um deles são os dados privados. Está bem? Esses são dados privados. Isso não pode ser alterado. Está dentro da função, não
pode ser
mexido, é privado. Outro caso de uso é evitar variáveis
globais e colisão de
variáveis. Portanto, podemos executar código sem declarar variáveis
globais quando usamos uma expressão de função imediatamente
invocada. Agora, deixe-me ilustrar
esse caso de uso. Então, vou copiar
algum código aqui. Vou simplesmente colá-lo
abaixo desses casos de uso. Aí vamos nós. Título também. Também sou o título do seletor de consultas. Estou pegando,
examinamos o arquivo HTML. Estou pegando essa div
aqui que tem a linha de maré da expressão de
função imediatamente invocada. Tudo bem, vamos pegar isso. Em seguida, estamos adicionando ouvintes de
eventos a ele. Uma é para passar o mouse, outra
para sair do mouse. Em ambos os casos, tudo o que
ele faz é mudar o cursor e trocá-lo novamente. E então temos um evento de clique que simplesmente registra no console o texto
interno disso. Tudo bem? Então, se
guardarmos isso, viremos aqui. Observe que meu cursor muda. Enquanto eu analiso isso. Quando eu clico, ele coloca
as informações, o innerHTML desse
elemento DOM no console. Agora, declaramos uma
variável aqui para fazer isso, pegar essa div e
poder usá-la. Mas vamos colocar uma
função em torno disso. Vamos começar
declarando uma variável. Vou mudar
isso em um momento, mas vamos
começar dessa maneira. Digamos que uma malha
é uma função inicializada. E deixe-me colocar tudo isso. Eu vou recuar isso. Então, isso pode estar dentro
desses colchetes encaracolados. Formate um pouco para nós. E então aqui está
o suporte ondulado
de fechamento para essa função. Agora temos uma função de inicialização. Agora, obviamente, se
salvarmos isso, não teremos mais a
funcionalidade aqui porque ela não foi invocada. Não chamamos essa função. Bem, sabemos que
podemos
invocar isso imediatamente fazendo
esse tipo de coisa. Então eu adiciono o príncipe
no final. Agora vamos ver se
temos essa funcionalidade. Eu subo, o cursor
muda, eu clico nele. Sim, nós temos. Então, pudemos invocar isso
imediatamente, mas ainda temos
uma variável aqui. Bem, não estamos capturando
nada que seja variável. Não há nada que
estejamos retornando
dessa função
para que precisemos ter a variável para ela. Vamos simplesmente remover essa variável. E vamos ver se isso funciona. Nós o salvamos. O que recebemos? Uma instrução de
função de erro de sintaxe retorna a requer
um nome de função. Então, o que está nos dizendo, o que esse
erro de sintaxe está nos dizendo é que isso é uma declaração de
função. Está esperando um
nome de função logo em seguida. Ele espera uma declaração de
função porque vê que a palavra-chave da
função é a primeira. Bem, vamos
transformar isso em uma expressão. E por que podemos fazer isso é simplesmente colocar parênteses ao redor. Agora, geralmente gosto de colocar meus parênteses
ao redor da função e fazer com que as marcas a
invoquem logo depois disso. Mas há muitas pessoas
que preferem fazer isso. Dessa forma. Os dois trabalham. Não importa a
maneira que você escolher para fazer isso. Os dois trabalham. Então, agora vamos salvar isso. Não temos mais
a sintaxe lá. Eu subo e vejo o
cursor mudar. Eu clico nele, eu o
vejo no console. Agora temos um código que está
sendo executado dentro de uma função. E não precisávamos declarar uma variável para que isso acontecesse. Essa variável agora está
dentro da função, não polui
o espaço global. Portanto, evitamos colisões de variáveis, o que significa que outra pessoa trabalhando em um projeto
ou algum resfriado que
trouxemos estava usando o mesmo nome de variável
e essas duas variáveis, Clyde, a última aquele
a ser declarado ou último a receber um valor é aquele
que tem precedência. Portanto, evitamos essas colisões e evitamos variáveis globais. Agora também podemos
ter dados privados. Obviamente, ninguém pode
acessar essa variável, mas esses elementos DOM disponíveis
fora dessa função, eles
precisariam apenas selecioná-la. Mas eu posso declarar
uma variável aqui, defini-la como igual a alguma coisa. Apenas pontuação ou algum tipo. Agora, isso não pode ser
acessado daqui em diante. A pontuação
será um ponto de exclamação. Bem, também poderíamos
configurar uma função dentro
dessa função e
retorná-la fora da função. Isso
nos permitiria mudar isso. E então governamos como esses dados
privados são alterados, o que é um padrão muito comum. Na verdade, esse é um padrão usado no padrão de módulo
tradicional, sobre
o qual falaremos quando lidarmos com
módulos neste curso. Como mencionei, com encerramentos vamos analisar
isso e você a expressão de função imediatamente
invocada quando lidarmos com os padrões
tradicionais do módulo. Portanto, é um ótimo padrão
aprender a aplicar esses conceitos. Mas esse sinal de
pontuação é privado. Se eu salvar isso, saia para clicar nele. Agora estamos vendo o
sinal de pontuação lá. Então, essas são expressões de função imediatamente
invocadas. Agora, o que eu gostaria de
fazer nos próximos tópicos, veremos alguns
dos trechos de código que
usamos em tópicos anteriores onde talvez eu tenha mencionado que isso poderia ser aprimorado com expressão de
função imediatamente invocada. Veremos como
podemos aprimorá-los. Veremos as mudanças que
precisamos fazer para usar um duvidoso. Tudo bem, então vamos
passar para o próximo tópico.
15. Aplicando IIFEs: Agora que apresentei o IFIS, vamos aplicá-los a alguns
dos exemplos de código que
estamos usando nesta seção. Esses são exemplos de encerramento
e agora vamos
adicionar o IFIS ao mesmo código. Agora, o primeiro exemplo
é a saudação atrasada. Agora, esse é um exemplo simples. Se você se lembra,
temos uma função. Chamamos de
passe de saudação atrasada em um nome usando setTimeout, essa saudação
é atrasada em 5 s. Agora, se fosse uma função que
quisesse ligar de algum lugar
, não usaríamos
um vazio para isso. Mas eu quero usar o NFV. Digamos que eu quisesse que isso fosse
exibido quando o arquivo fosse carregado. Então eu quero usar o NFV para este exemplo porque ele tem
essa passagem em uma variável. Então, eu quero dar um
exemplo disso. Vamos seguir em frente e
ver como faríamos isso. Muito simples. Só precisamos remover isso. Não precisamos mais disso. E também podemos remover
essa parte. Agora, queremos transformar isso em
uma expressão para que seja válida e então eu coloco parênteses
em volta dessa forma. E então, para invocá-lo, colocamos parênteses novamente. Agora, como você sabe, existem formatos
diferentes para isso, esse último Perrin também pode
sair aqui. Eu simplesmente prefiro essa estrutura
específica. Agora, o que precisamos fazer
é passar a variável, então eu a coloco
dentro dos parênteses. Isso é tudo o que precisamos para fazer isso. E aí temos nossa saudação
tardia. Então, deixe-me voltar aqui e
abrir o console. Aqui está nossa saudação de quando
carregamos a página pela primeira vez. Agora, vamos salvar
isso e ele será recarregado. E depois de 5 s, devemos receber a
mesma saudação novamente. Basicamente, estamos apenas
removendo a linha que invoca essa função e
estamos lidando com ela aqui. Isso é realmente o que
estamos fazendo com uma expressão de
função imediatamente invocada. Tudo bem, agora vou
comentar isso. E vou copiar outro trecho de código que
usamos como exemplo. E essa foi uma função
inicializada. Vá em frente e cole isso.
E se você for membro, está inicializando dois botões. E quando eles são
clicados, incremente a variável de contagem e
, em seguida, faça login no console. Agora, para usar isso, preciso vir aqui e descomentar esses
botões para que eles
apareçam na página HTML. Então vá em frente e atualize isso. E digamos que esse. Vamos ver se
eles estão aparecendo. Nós os temos aqui. Ok. Apenas certifique-se de que o código esteja
funcionando antes de prosseguirmos. Sim. Tudo bem. Então, estamos bem. Agora, quando temos
algumas coisas a serem inicializadas e não
inicializamos uma função como essa. Essa geralmente é uma boa
aplicação para quem tem dúvidas. Como essa função está funcionando, só será executada uma vez e será
quando a página for carregada. Por que armazená-lo em uma variável? Então, podemos ligar mais tarde. Ou por que declarar a função
para que possamos chamá-la mais tarde. Vamos invocar o código, executá-lo e
terminar com ele. Então, vamos remover
essa declaração lá, e vamos removê-la aqui embaixo. Mais uma vez, tudo o que precisamos fazer é cercar isso com Krenz. Isso o torna válido. E depois colocamos os planos
para invocá-lo. Agora, isso realmente
vai fazer a mesma coisa para nós. Então, vamos salvar isso,
a página será recarregada. E vamos
tentar esses botões. E eles ainda estão trabalhando. Então, dois exemplos rápidos em que
pegamos algo que fizemos com fechamentos e adicionamos uma expressão de
função imediatamente invocada. E, especialmente, o segundo
exemplo é ideal para o IFIS. Tudo bem, vamos seguir em frente
e deixe-me dar a você a chance de experimentar um
exercício com eles.
16. Início do exercício: IIFEs: Depois de entender
a estrutura de uma expressão de
função imediatamente invocada, ela não é tão
difícil de criar. Normalmente, você está convertendo
algo que já existe em um,
o que torna tudo ainda mais fácil. Mas eu quero que você
faça um exercício. Esse é um
conceito importante e acho que é importante fazer um
exercício sobre esse conceito. Então, vamos dar uma olhada no que
eu gostaria que você fizesse. Tudo bem, aqui está um
código inicial e basicamente tudo o que ele está fazendo é criar uma mensagem dentro
dessa variável de mensagem, dizendo algo como
hoje é qualquer que seja a data e depois
o dia do mês. Isso é tudo que está fazendo. Isso
é algo que pode ser exibido na página inicial
ou algo parecido. Então, o que eu gostaria que você fizesse
é transformar isso em uma dúvida e, para ver
se está funcionando corretamente, basta registrar os resultados
no console. Então, vamos enviá-lo para o console. Ele deve ser produzido
assim que a página for carregada e
desconectada do console. Normalmente, você pode querer exibir essa mensagem dentro de algum
div ou algo parecido. Faremos o console e
isso será bom o suficiente. Tudo bem, vá em frente
e experimente. E quando estiver pronto para revisar, vá para o próximo tópico.
17. Fim do exercício: IIFEs: Ok. Espero que não tenha sido muito difícil. Eu não pretendia que isso
fosse muito difícil. Agora, só para mencionar que uma
das vantagens de
transformar isso em um FE é que, de repente ,
três variáveis estão
atualmente no espaço global, que não estarão
na meta do espaço. Tão grande vantagem, eles estão
tornando isso duvidoso. Então, vamos fazer isso. Vou entrar na
função primeiro. E então, meus colchetes, vou pegar
o código agora e colocá-lo dentro
dessa função. Observe que eu não dei um nome
à função, que geralmente significa que estou no processo de
criar uma duvidosa. Mas preciso colocar
isso entre parênteses,
transformá-lo em expressões
para não obtermos um erro de sintaxe e, em seguida,
usar parênteses para invocá-lo. Agora, a única coisa que
mencionei que queremos fazer é apenas exibir
isso no console. Então, deixe-me seguir em frente e fazer isso. Mensagem de registro de pontos do console apenas para ter certeza de que está
funcionando corretamente. E vamos salvar isso. Vá até aqui e dê
uma olhada no console, veja se recebemos uma mensagem. Hoje é segunda-feira 19. E isso é realmente
o que é o dia da semana e
a data do mês. E isso está funcionando para nós. Então, muito simples. Mas um
padrão muito importante e o JavaScript imediatamente invocaram
expressões de função ou, se ele estiver, tudo bem, vamos seguir em frente.