Transcrições
1. Apresentação: [MÚSICA] Ei, bem-vindo
a esta aula. Como todos sabemos, aprender
qualquer nova habilidade pode ser desafiador e JavaScript não
é exceção. O JavaScript tem
uma ampla gama de recursos e coisas
para as quais pode ser usado, e isso muitas vezes pode
deixar os iniciantes em uma situação difícil
se perguntando por onde começar, então é por isso que
criei isso classe. Esta é a Parte 2 da
classe que se baseia na fundação que você
aprendeu na Parte 1. Se você não participou da Parte 1, se esqueça de passar por esta
aula primeiro, a menos que você já tenha alguma
experiência em JavaScript e queira abordar os
tópicos desta seção. Se você não fez uma
das minhas aulas antes, meu nome é Chris e
eu construo
sites há mais de 20 anos. Também tenho ensinado essas habilidades há mais de sete
anos, ambas as aulas de vídeo ao lado dos principais campos de
inicialização de desenvolvimento web também. Esta classe tem muitos assuntos
JavaScript, incluindo loops e instruções
condicionais, uma aparência profunda de
objetos, matemática, data
e temporizadores, juntamente com ela
desenhando para a tela. Todos esses tópicos que abordei de forma clara e estruturada
ao mesmo tempo em forma clara e estruturada que criamos
projetos práticos à medida que avançamos, incluindo
exemplos de casos de uso do mundo real e também alguns mini desafios ao longo com a construção um jogo de chef de pizza para combinar muitas partes do que
você aprendeu. Este projeto
será razoavelmente grande, mas vamos dividi-lo, para que você possa ver como todas
as peças se encaixam. Mais tarde,
descobriremos algumas
das partes mais complicadas,
como JavaScript assíncrono, escopo, içamento e fechamentos. Antes de terminar
com mais dois
projetos finais , vamos um
pequeno aplicativo chamado Deixando tão cedo, que é um pop-up de intenção de saída, que é usado para
atrair visitantes com uma oferta quando eles tentam
sair do seu site. Se tudo estiver concluindo
a classe
funcionando fielmente o carrossel de
imagens JavaScript. Ele inclui uma pasta de
projeto que adicionaremos à medida que
progredirmos ao longo desta classe e também se desenvolverá como uma referência útil
no futuro também. Obrigado pelo seu interesse
nesta aula e
te vejo na primeira lição.
2. Baixar a pasta de projeto: Se você já concluiu a primeira
parte desta classe, você pode continuar com os mesmos arquivos iniciais
que usamos na parte 1. Nesta parte 2 da
aula começaremos na Seção número 6, até
o fim. Começarei na primeira
lição que é para loops. Se você tiver isso,
você está completamente pronto para a próxima lição. Se você estiver pulando para a parte
2 sem tomar a parte 1, o
que também é completamente bom, mas você precisará ir
até github.com e baixar os
arquivos iniciais que
vamos usar
ao longo disso classe. Siga o link que você
pode ver na tela aqui. Depois de chegar a esta página, clique no botão de carvão verde e faça o download
como um arquivo zip. Abra esta pasta do projeto
dentro do seu editor de
texto favorito. Vou usar o
Visual Studio Code, mas você pode usar o
que preferir. Isso é tudo o que você
precisa para começar , e eu te vejo em seguida. Começaremos dando
uma olhada em para-loops.
3. Compartilhe seu trabalho em Skillshare!: Ao fazer qualquer curso, é muito importante
não adquirir o hábito de acompanhar apenas para marcar outra palestra. Reserve um tempo para
processar cada lição, revisar o código que você escreve e pensar em como você mesmo pode abordar essas
soluções. Com isso em mente, esta
aula é baseada em projetos e isso lhe dá
a oportunidade de
realmente criar algo
pessoal e único. Você não precisa se perder
muito e se
desviar da aula
e pode até mesmo dar um passo atrás depois de
terminar a aula e voltar e fazer algumas mudanças no
projeto depois. Isso realmente lhe dará
uma boa chance de praticar o que aprendeu
fora da aula. Além disso, lembre-se de compartilhar
seu projeto também aqui no Skillshare e só
vou dar uma olhada, mas também inspirará
outros estudantes. Para obter mais informações
sobre o projeto da
turma, acesse a guia Projeto
e Recursos, onde você pode não apenas
fazer o upload do seu projeto, mas também ver
outros projetos de classe. Com isso em mente, estou
ansioso para ver o que você cria e carrega
aqui no Skillshare.
4. Para Loops: Bem-vindo de volta. Esta
seção será sobre loops. Vamos começar as
coisas com um loop for-loop. Quando começamos a trabalhar
com matrizes anteriormente, analisamos algumas maneiras
diferentes de
repetir determinadas tarefas
usando esses loops. Os tipos de loop que
observamos foram map, e forEach, ambos
eram métodos de matriz. Loops significam que podemos repetir
tarefas com muito mais facilidade. Mesmo que existam
diferentes tipos de loops, eles geralmente continuam repetindo
uma tarefa várias vezes. Muitas vezes, a principal
diferença é como dizemos ao loop para interromper esse mapa, e os loops forEach
eram métodos de matriz, mas os loops não são
exclusivamente para matrizes. Há também diferentes
tipos de loops que podemos usar para poder fazer loop sobre praticamente
qualquer coisa que precisemos. Este vídeo vai se
concentrar em um loop for-loop. É assim que um
loop básico se parece. Ele define um pouco como uma
função ou uma instrução if. Observe dentro dos suportes
que são dois ponto-e-vírgula. Eles são usados para passar as expressões livres que
configuram como nosso loop funcionará. Um exemplo muito simples aqui é
apenas usá-lo para aumentar o número e veremos alguns exemplos melhores
em apenas um momento. Mas, para a primeira expressão, ela contém o valor
inicial ou inicial do nosso loop. Se quisermos apenas começar com um número zero ou
aumentar a cada vez, configuramos uma variável como zero, assim. Em segundo lugar, temos
uma condição e aqui veremos que temos o
número é menor que 10. Essa condição determina se
o loop deve continuar. Se isso for verdade, o
loop continua. Se for falso, o loop
terminará. Por fim, se não fizermos
algo em cada loop, a segunda condição sempre
será verdadeira. Aqui aumentamos o valor
do número em um em cada loop. Portanto, podemos
verificar a condição após cada uma dessas alterações. Para percorrer este exemplo
após cada loop ser executado, o número será aumentado um até atingir o número 10, fazendo com que a segunda instrução seja então resultando em false, fazendo com que o loop em seguida, termine. Ou seja, este exemplo específico, registraremos 10 valores, que serão zero
até o número nove. Se você tiver a variável já declarada fora
do loop for-loop, você pode deixar de fora
e apenas incluir a segunda e a terceira instruções, e as coisas ainda serão
executadas da mesma forma que antes. Além disso, vale a pena
notar que você verá muitos exemplos com
o nome da variável, a letra i, que é
abreviação de inicializador ou valor inicial. Isso geralmente ocorre se estivermos
usando essa variável apenas para os propósitos
do loop e não precisarmos de nomes de variáveis descritivas em outro lugar. Observe que ainda devemos manter o ponto e vírgula no
lugar para que possamos separar
claramente esses três
valores em alguns exemplos. Vamos pular para
nossos arquivos iniciais. Para esta seção, vá
para a Seção número 6, que é loops e condicionais. A primeira lição,
que é para-loops, salta para a página de índice, que está
praticamente vazia por enquanto. Em seguida, copiaremos o caminho para isso e, em seguida, colaremos isso
dentro do navegador. Não temos conteúdo
no momento, apenas o título for-loops
e, em seguida, o script vazio na parte inferior para trabalharmos. Vamos pular para dentro
da seção de script e podemos começar a criar
nosso primeiro for-loop. Como olhamos antes, usamos a palavra-chave for, o suporte iniciamos nossas declarações
livres
e, em seguida, as chaves. Para este exemplo,
vamos simular alguém comendo uma pizza
com 10 fatias diferentes. Então vamos deduzir uma fatia de pizza após cada um desses loops. Primeiro de tudo, nosso
inicializador ou nossa variável, que chamaremos de fatias. Definiremos que este seja
o valor inicial de 10 e no próximo manteremos
o loop em execução, desde essas fatias sejam
iguais ou
maiores que o valor de
um, adicione um ponto-e-vírgula. Em seguida, deduziremos o valor das fatias pelo valor
de uma a cada vez. Agora só para recapitular, vamos começar com 10 fatias ou o valor de 10. Depois que o loop for concluído, isso deduzirá uma fatia
para então ser igual a nove, nove é maior ou igual a um,
portanto, o loop continuará funcionando. Em seguida, ele será executado pela segunda vez. Então isso
deduzirá as fatias de pizza para oito e depois sete, depois seis. Ele continuará funcionando até que o valor seja maior
ou igual a um. Dentro das chaves, adicionamos o código que
você deseja executar. Veja um exemplo simples, podemos fazer um log de console com
o valor de fatias. Isso
será deduzido de 10 até um. Depois disso, um segundo log
do console com o texto de cada fatia. Também podemos adicionar coisas como instruções
condicionais
dentro daqui também. Essa instrução
condicional verificará se as fatias são iguais
ao valor de uma. Se for, estaremos no lugar em um registro de console com o
texto sem fatias restantes. Vamos salvar isso e
entrar nas Ferramentas do Desenvolvedor. clique com o botão direito do mouse e “Inspecione”
no console. Vemos que o valor de 10
no primeiro loop é então deduzido pelo valor
de um de cada vez. Nós chegamos
até o valor de um e, em seguida, ele toma
uma nota das fatias restantes. Algo que você pode ver,
mas provavelmente não
tanto está faltando um segundo valor, que é essa condição. Precisamos sair
no ponto e vírgula no lugar e
antes de testarmos isso, você já pode estar
detectando um problema. Se você não tiver condição. Não temos como
parar um loop. Isso continuará
funcionando infinitamente. Isso é algo que
precisamos ter cuidado ao criar loops. Devemos garantir que
a condição dos loops eventualmente se torne falsa. Caso contrário,
acabaríamos em um loop infinito,
o que, portanto, faria com que
o navegador falhasse. Não faça isso e não
acompanhe esse exemplo. Mas vou mostrar o que acontece dentro do navegador. Se salvarmos isso, atualize. Vemos que o loop é executado
milhares de vezes, o que
ocupa todos os recursos do navegador, fazendo com que ele eventualmente falhe. Para evitar esse esmagamento
ou esse loop infinito, precisamos
usar manualmente a palavra-chave break dentro do loop quando
queremos que ela pare. Por exemplo, se formos
para esta seção inferior, saberemos dentro da instrução if
este é o último loop. O que podemos fazer é
adicionar a palavra-chave break. Isso então sai
do loop e seguida, impede que o
código seja executado. Podemos testar isso
abrindo o navegador mais uma vez. Abra a Página Índice
e, em seguida, entre nas Ferramentas
do Desenvolvedor e
no console e nosso loop, agora
funciona conforme o esperado. Outra coisa útil que
podemos fazer com for-loops é criar
vários elementos, como itens de lista. Usando um loop, podemos
criar, digamos, 10 elementos com muito
menos código do que faríamos se
escrevêssemos isso 10 vezes. Vamos fazer isso
dentro do script, criaremos uma
constante chamada ul, onde criaremos uma
nova lista não ordenada. Fazemos isso com
Document.createElement. Passando os elementos ul
que você deseja criar. Pouco antes de saltarmos para a
criação dos itens da lista, anexaremos nossa
lista não ordenada ao corpo. Pegue o corpo com
Document.body.appendChild, passando nossa variável ul. Só voltando ao que
olhamos antes, vamos modificar
nosso exemplo de pizza e substituí-lo pelo nome
da variável i.
Lembre-se que eu é uma convenção de
nomenclatura comum para uma variável dentro de um loop. Inicialmente, definiremos isso
como um valor de um. Vamos fazer isso
da maneira inversa de antes. Começaremos com o valor
inicial de um
e, em seguida, manteremos
o loop em execução enquanto i for menor ou igual
ao valor de 10. Portanto, precisamos aumentar isso pelo valor de
um em cada loop, que fará com que o
loop seja executado 10 vezes. Podemos mover todo o
conteúdo de dentro
daqui e, em seguida, criar
nossos itens de lista. Vamos criar nosso
item de lista, selecionaremos o documento.CreateElement
passar no item da lista. Armazene isso dentro de
uma constante chamada li. Isso nos dará
um item de lista vazio. Precisamos então
colocar o conteúdo dentro da tag de abertura
e fechamento. Podemos fazer isso com
documentos.CreateTextNode, e podemos colocar
em qualquer exemplo de texto que
quisermos dentro daqui. Em vez de uma string normal, vou inserir uma
variável usando os backticks. Diremos que o item de lista colocado em nossa variável com o símbolo $ e as chaves. Sabemos de cima
que temos uma variável chamada i, que é igual
ao valor de um. Então, se você continuar aumentando
pelo valor de um para cada loop. Podemos verificar isso
colocando isso dentro daqui. Isso deve começar com o
valor do item da lista um, item de
lista dois e assim por diante. Tudo isso dentro de uma
constante, digamos texto. Em seguida, podemos mesclar esses
dois acessando
o pai, que é o
item de lista que usa appendChild. Em seguida, coloque nosso texto dentro
do elemento de lista. Finalmente, quando criamos cada
um desses itens da lista, queremos nos empurrar
para nossa lista não ordenada. Da mesma forma que
fizemos com o item da nossa lista. Selecionamos nossa
lista não ordenada AppendChild, onde passamos nosso item de lista. Vamos verificar isso,
atualizar o navegador. Isso só precisa ser i para
corresponder à atualização da variável. Agora vemos o
valor do item de lista um todo o caminho até
listar o item 10. Como você pode imaginar, se
criássemos essas 10 vezes separadas, isso resultaria
em muito mais código. Usar esse loop faz dele
um exemplo muito mais curto.
5. ...em & For... de: Agora vamos cobrir mais
dois tipos de loops, que é chamado for-in
e também for-of. Eles são muito parecidos e ambos
passam por cima de algo
como você esperaria, mas a principal diferença é
o que eles podem fazer um loop. Vamos abrir os
arquivos iniciais e ver o que temos. Na barra lateral, pulando para a lição Número 2
nesta seção, que é for-in e for-of, e então abra isso
dentro do navegador. Primeiro de tudo, vemos uma seção
for-in que tem um objeto de produto com várias
propriedades aninhadas no interior. Como você pode esperar, é
assim que funciona um loop for-in. Usamos esse tipo de
loop para fazer loop sobre as propriedades
dentro de um objeto, como o nome e o tamanho. Agora, isso terá
a seção for-of, e isso é usado para fazer loop
sobre objetos iteráveis. Um objeto iterável é basicamente alguns deles
sobre o loop, como uma matriz ou uma lista de nós. Vamos começar no topo
com nosso loop for-in, e vamos usar isso
para fazer um loop sobre nossos objetos de produto. Podemos fazer isso logo abaixo. Isso se parece um pouco
com o nosso for-loop do vídeo anterior, configuramos a palavra-chave for, os colchetes e, em seguida,
as chaves curly. Saltando para o primeiro
conjunto de colchetes, e é assim que funciona um loop
for-in. Configuramos uma variável
e chamaremos essa propriedade, pois estamos fazendo loop sobre todas as propriedades
dentro desse objeto, que está em nosso objeto de produto. É daí que vem o termo
for-in, temos a
palavra-chave for e, em seguida, a palavra-chave
in dentro dos colchetes. Estamos fazendo um loop sobre esse objeto de
produto completo e, em seguida, estamos armazenando o valor
da propriedade dentro dessa constante. Vamos ver como é
com um log de console do
valor da nossa variável, que é propriedade, atualização, e vemos o valor do SKU, o nome, o tamanho
e a cor. Isso nos dá o
valor da chave, mas e o valor
real da propriedade como camisa legal, média e azul? Bem, também podemos fazer
isso acessando nosso produto e, em seguida, usando
os colchetes. Vamos dar uma olhada em como isso fica dentro
de um registro de console. Podemos usar os ticks traseiros
para inserir uma variável e começaremos inserindo
o valor da propriedade. Estas são apenas as
teclas que veremos já dentro do console, mas depois adicione
dois pontos para separar isso e, em seguida, insira
nossa segunda variável. A segunda variável será cada um desses produtos. Vamos pegar o produto
e, em seguida, podemos usar
os colchetes, para restringir isso a
uma determinada propriedade. Estamos passando
o valor de SKU, nome, cor ou tamanho. Se salvarmos isso e
atualizarmos, agora criamos uma nova string para cada uma
dessas propriedades, que inclui a chave e também o valor
da propriedade. É assim que um loop for-in
funciona para fazer loop sobre um objeto. Vamos agora dar uma olhada em for-of. Quero comentar
esta seção e, em seguida, descer para baixo
abaixo de nossas permissões. Novamente, isso começa com a palavra-chave
for, os colchetes e as chaves curly, e também leva uma variável. Digamos que o valor const, que será definido para cada um dos valores
dentro da matriz. Desta vez, em vez de usar
a palavra-chave in que usamos
e, em seguida, passe
exatamente o que queremos fazer um loop over. No nosso caso, é a
matriz de permissões logo acima. Isso está em permissões
e, em seguida, dentro
das chaves, podemos acessar nosso valor. No primeiro loop,
o valor é usuário, o segundo loop é editor
e, em seguida, administrador,
salve e
atualize, e há nossos três
valores dentro do console. Como você pode ver dentro de
seus comentários no topo, coisas como uma lista de nós
também podem ser colocadas em loop. Lembre-se, quando
usamos algo como seletor de
consulta para
obter vários elementos, uma lista de nós é o que recebemos de volta. Para experimentar isso, também precisamos de
alguns elementos para fazer loop. Vou pular para fora
desses scripts, criar uma lista não ordenada com alguns
itens de lista de amostra dentro. Vamos duplicar isso mais duas vezes em vez de
girar Número 2 e 3, e então podemos fazer um loop sobre
nossos três itens da lista, que
retornarão uma lista de nós, portanto, podemos
usar o loop for-of. A etapa 1 é acessar todos esses
três itens da lista. Vou logo acima do nosso loop for, criar links de chamada constantes, pegá-los com
Document.QuerySelector, na verdade, precisamos de QuerySelectorAll
já que estamos acessando vários elementos e uma vez
que você pega nossa lista itens. Agora, em vez de acessar
nossas permissões, o que vamos fazer
é acessar todos os links, que são nossos três itens da lista e, em seguida, alterar o nome da
variável para o link. O valor do link em nosso primeiro loop é
o primeiro item da lista, o segundo item da lista
e, em seguida, o terceiro. Podemos fazer o que
quisermos com esses links. Para este exemplo,
vou acessar nossos links e, em seguida,
usar addEventListener. Ouça para um clique
em qualquer um desses. Em seguida, isso executará uma função, passaremos as informações
do evento , criaremos um alerta. Para acessar o conteúdo
dentro de cada um
desses itens da lista,
como 1, 2 e 3, podemos fazer isso acessando
as informações de eventos, selecione e. target, que são as informações sobre isso item de lista específico
que foi clicado
e, em seguida, exibe o
innerHTML desse elemento. Vamos experimentar isso.
Agora, se atualizarmos, temos nossos links gratuitos na parte superior, vamos clicar no Número 2,
há o InnerHTML. O Número 3 e também o Número
1 também funciona corretamente. Essa é uma variação
realmente útil no for-loop, que podemos usar para fazer loop
sobre coisas como matrizes e lista de nós, e
também objetos também.
6. O que você achou desta tradução?: Na minha opinião, enquanto
os loops parecem um pouco mais simples do que os quatro loops
que procuramos antes. A configuração básica parece novamente semelhante a muitas outras
coisas em JavaScript, como uma função básica e instruções
if e até mesmo
o loop for também. Um loop while
continuará funcionando
enquanto uma condição
estiver definida como true. Para este exemplo, temos
uma variável numérica simples e, em seguida, o loop
continuará em execução enquanto o número
for menor que 30. Essa verificação é executada antes que o código no
loop seja executado,
portanto, se for falso, o
loop será interrompido. Assim como no loop for, também
precisamos de uma maneira de realmente parar as coisas para que ele não se
transforme em um loop infinito. Fazemos isso dentro do
loop incrementando o valor do número
em um em cada loop. O que significa que ele será executado 30
vezes antes de parar. Vamos aos nossos
arquivos iniciais e experimentar isso. A próxima lição que
precisamos é a número 3. É a seção loop while. Abra isso e também
dentro do navegador também. Como você pode ver, temos
um arquivo inicial vazio com o script na parte inferior. O que faremos dentro daqui é configurar algumas variáveis. Primeiro de tudo, uma constante
chamada StadiumCapacity, e defina isso igual
a um valor de 100. Esta é a
capacidade do estádio e, em seguida ,
configuraremos uma segunda variável, que
será para o número de fãs que entramos
atualmente. Como isso pode ser aumentado, precisamos usar a palavra-chave e definir isso igual a um
valor de currentlyEnter, que começará
no valor de zero. O que queremos fazer é continuar executando um loop enquanto o valor de CurrentlyEnter é
menor que o StadiumCapacity. Um loop while é ideal para isso. Configuramos nossa palavra-chave while, os colchetes e, em seguida, as chaves
curly logo depois. O que vamos fazer
é manter esse loop em execução enquanto o valor
de CurrentlyEnter, que é zero, é
menor que o StadiumCapacity. Basicamente, se zero
for menor que 100, o código dentro
daqui será executado. Colocando um registro de console
com um texto de enter, e devemos ser
capazes de ir até o console e verificar isso. Mas pouco antes de fazermos isso, vamos dar um passo atrás e
dar uma olhada nesse loop. Se pensarmos sobre
isso, queremos
dar uma olhada em nossa condição que eles entraram atualmente é menor do que a capacidade do estádio. No momento, não temos como alterar esses dois valores
variáveis. Basicamente, esse sempre
será o valor verdadeiro. Isso resultará
em um loop infinito e novamente causará uma falha
dentro do navegador. Para executar esse loop while apenas
uma certa quantidade de vezes, precisamos de uma maneira de
aumentar o valor de CurrentlyEnter em cada
loop. Isso é bem simples. Nós apenas acessamos nosso valor
e, em seguida, usamos plus plus, o
que aumentará isso
pelo valor de um em cada loop
até o valor de 100. Uma vez que isso chegue ao valor de 100, essa condição
não será mais verdadeira, o que significa que isso
fará com que nosso loop seja interrompido. Vamos verificar isso
dentro do navegador, atualizar e pular
para o console. Bom e vemos que
nosso texto de entrada foi repetido 100 vezes. A variação desse loop
while é do-while. Esta é uma
versão comutada deste loop while. Antes de dentro dos slides, mencionei que o
código dentro desse loop sempre
será executado depois que essa
condição for verificada. Basicamente, se isso
resultar em falso, o código dentro desse loop nunca
será executado nem uma vez. Podemos inverter isso e garantir que o código seja executado pelo menos uma vez e depois executar
a verificação depois. Isso é útil se quisermos
sempre garantir que o código seja executado pelo
menos uma vez antes que
o loop seja interrompido. Para fazer isso, logo acima nossa seção while,
criaremos uma seção do. Vamos dizer que sim,
abra as chaves encaracoladas, e como sempre
queremos que isso funcione uma vez, apenas
pulamos
diretamente para as chaves encaracoladas, não
precisamos
adicionar nenhuma condição. Em seguida, podemos pegar nosso código do loop while. Corte
isso fora do lugar. Adicione isso à seção do. Vou remover as
chaves encaracoladas do loop while. Como você pode ver, o código agora fica dentro da seção do, o que significa que isso
sempre será executado pelo menos uma vez antes mesmo de
realizarmos nossa verificação. Nosso cheque ainda é verdade, isso continuará funcionando
pela segunda vez, no nosso caso, até 100. Vamos verificar isso. Podemos salvar isso e atualizar o navegador. Ainda obtivemos exatamente os
mesmos resultados de antes. Podemos testar isso
definindo o valor de currentlyEnter como 100, o que então define
isso como falso. Se agora salvarmos isso e
atualizarmos, veremos nosso valor de log de
console único de enter porque nosso código é executado primeiro e, em seguida, ele
executará a verificação dentro
do loop while. Essa é apenas uma
alternativa,
dependendo se sempre queremos que
o código seja executado primeiro ou primeiro teste a condição antes de executar
qualquer código dentro do nosso loop.
7. Se / Else Declarações & Nidificação: Para este vídeo, vá para a seção de instruções if-else e também abra isso
dentro do navegador. Você pode ver na parte superior
que temos um objeto de usuário já configurado e também if
instrução logo abaixo. Então, usamos
instruções if algumas vezes já durante exemplos
anteriores. Não há muito mais para adicionar a eles do que o que
já abordamos. Eles simplesmente executam algum código
entre essas chaves. Se a condição dentro
daqui estiver definida como verdadeira. Usando este exemplo, temos
um objeto de usuário na parte superior. Isso resultaria em verdade, já que temos um objeto presente, o que significa que nosso
log do console funcionará. Se o usuário fosse desconectado, talvez definisse nossa variável nula,
assim,
para que o usuário
seja igual a nulo, que resultaria
em um valor falso e o código dentro do if
declaração não seria executada. Então, aqui estamos lidando
se a condição for verdadeira. Mas e se também
quisermos
lidar se a
condição for falsa? Bem, é aqui que outras
declarações entram em jogo. Nós os colocamos imediatamente após a instrução if e
esse bloco de código será executado em todos os casos que não são cobertos
pela seção if. Temos esses
exemplos semelhantes configurados dentro dos arquivos iniciais e aqui só lidamos com a condição se o
usuário estiver logado. Você pode estar pensando,
por que não apenas lidar com a
condição de logout abaixo disso. Ou poderíamos fazer
algo assim. Poderíamos fazer um log de console
ou qualquer código que você queira, onde podemos dizer que o
usuário está desconectado. Bem, vamos testar isso
e ver o que acontece se
atualizarmos e pular
para o console. Aqui podemos ver que o log
do console foi executado duas vezes. Temos o usuário
conectado e também o usuário está desconectado. Portanto, obviamente, para algo sensível à
segurança, como um usuário que está sendo
logado ou desconectado, queremos apenas uma
dessas condições ser executada. Isso, podemos configurar
nossas declarações if, que temos acima, seguidas
pela declaração else. Vamos remover o registro do console. Estou colocando a seção else e adiciono nosso código dentro daqui. Vamos atualizar e vemos que o
usuário está logado, pois temos um objeto de usuário
presente na parte superior. Se também mudarmos isso
para ser o oposto e definirmos que o usuário seja igual
a um valor falso de nulo. Em seguida, isso deve ser o
usuário desconectado. Se quiséssemos, também poderíamos adicionar várias instruções if para e vamos apenas empurrar nossa declaração else para
baixo. Então, no meio, podemos adicionar uma segunda declaração if,
assim como fizemos acima. Podemos verificar uma segunda condição
, como um usuário ou função, que está atualmente definida como admin. Podemos verificar se este é um valor específico e se ele está dentro das
chaves, faremos um registro de console,
digamos, Ei administrador,
teste isso, atualize. Agora vemos que o usuário
está logado e eles também são a função de administrador. Isso funciona, mas isso também
apresenta um problema também, precisamos ter muito cuidado
com esse tipo de configuração. Porque essa declaração else, que teremos
na parte inferior imediatamente segue a
segunda instrução if. Isso significa que agora a seção
else só será executada se a função do usuário não
estiver definida como admin, o que não faz sentido. Então, tínhamos um usuário como nulo, então com o não estamos conectados. Atualizar. Isso agora
lançará um erro, pois estamos tentando acessar
a função de ponto do usuário, que não está mais
disponível porque
não temos mais nossos objetos de usuário. Para esse tipo de uso
desse exemplo para
torná-lo um pouco mais sentido
e para ser mais viável, só
queremos verificar
se a função do usuário é igual ao administrador, eles realmente se conectaram. Para fazer isso, podemos
aninhar nossas declarações if cortando a
segunda declaração if. Podemos colar isso dentro
do primeiro. Isso nos traz de volta
ao primeiro exemplo. Temos duas verificações de nível superior. Temos a instrução if, o usuário está logado
seguido da seção else logo abaixo. Em seguida, a instrução if
que está aninhada dentro, só
será arruinada se o
usuário realmente tiver efetuado login. Se o usuário estiver conectado, esse log do console será executado. Então, se eles também estiverem logados como
função de administrador, o segundo log do console também será
executado também . Vamos experimentar isso. Atualize e o
erro agora está apagado. Vemos que o usuário está desconectado porque o usuário está definido como nulo. Vamos restabelecer isso,
o nome para ser igual a qualquer coisa na
função de volta ao administrador. Com isso agora em vigor, agora
temos um usuário. Portanto, o primeiro
log do console deve ser executado. Também temos uma função de usuário
que é igual a admin. Agora devemos ver dois registros de
console dentro daqui. É assim que podemos usar instruções if else de
nível superior e também como podemos aninhar uma instrução
if dentro também. Se você quisesse,
você também poderia ir ainda mais longe logo após
a seção if aninhada, também
poderíamos colocar
em uma seção else também para que possamos
fazer um log do console. Para esta seção,
sabemos que o usuário está realmente logado, mas também queremos verificar
se ele não é o administrador. Então, aqui, isso será executado
se eles forem o administrador. Caso contrário, vamos apenas
dizer, Ei usuário, atualize. Ainda vemos hey admin, já que
a função está definida para isso. Mas se mudarmos isso
para ser assinante, a instrução if aninhada agora
é falsa, o
que significa que a
seção hey user agora será executada. Se você quiser. Você também
poderia ir tão fundo quanto quiséssemos aninhando várias seções se else
dentro das aninhadas também. Mas devemos ter cuidado para não
exagerar e tornar o código
difícil de ler e também entender
para outros desenvolvedores também. Como regra geral,
geralmente podemos cobrir a maioria
dos casos de uso sem precisar
ir ao fundo. Então, se você achar
que talvez tenha três ou quatro níveis de profundidade
com declarações ou verificações if, geralmente
há uma
maneira melhor de fazer as coisas.
8. Se não: Dentro da pasta desta lição, que é a seção else if, você encontrará logo abaixo
dentro do script, temos o mesmo exemplo
do vídeo anterior. Aqui estamos lidando com duas condições
de nível superior
que verificamos. Primeiro de tudo, se o usuário
estiver conectado e, em seguida, seção captura o que acontece se o usuário não estiver conectado. Dentro da seção logado, também
temos uma seção
if else aninhada também. Adicione uma saudação diferente se
o usuário for igual ao administrador. Temos duas opções
no nível superior e também duas opções aninhadas também. Mas e se
quiséssemos uma terceira opção também? Para isso, também temos mais if. Vamos dar uma olhada nisso,
vamos simplificar esse exemplo removendo
as instruções aninhadas. Dentro daqui,
removeremos o aninhado se mais nos deixar com um simples
login ou desconectado. Se você se lembra
do vídeo anterior, demos uma olhada em como lidar
brevemente com uma terceira condição adicionando uma segunda declaração if,
assim como esta. Mas o problema que isso
nos dá é que a seção else agora
está conectada à nossa
segunda declaração if. Essencialmente, o que significa que
nossa primeira
declaração if agora está desconectada. Se ainda quisermos
manter todos os três conectados sem relação
entre si, podemos transformar este segundo em
outro caso se, em outro lugar. Pouco antes da seção if
, podemos adicionar uma segunda
condição dentro daqui. Primeiro de tudo, queremos verificar
se o usuário está logado
e, em seguida, usando o comercial
duplo, também
podemos fornecer
uma segunda verificação. Podemos verificar se o user.role
é igual ao assinante
e, se for, executaremos
o código dentro daqui. Agora vamos colocar em um registro
simples do console dizendo que a seção else se foi executada, salve isso e depois no navegador e veremos
o que acontece dentro daqui. Vemos o texto do
usuário conectado. Você pode estar se perguntando por que
vemos o texto de apenas usuário conectado e não também
a seção else se foi executada porque depois de
todo o usuário está presente e também o user.role
é igual ao assinante. Bem, o motivo é porque apenas uma dessas
seções será executada. Se a condição tiver sido atendida, o código interno será
executado e não irá mais longe no resto
dessas seções. Efetivamente, somente a
primeira partida será executada. Se quisermos que seja mais
específico com a primeira seção, também
podemos copiar
este user.role solte isso na primeira seção e também podemos verificar se
isso é igual a admin. Como nossa função de usuário é
igual ao assinante, agora
eles devem ser falsos. Porque em nenhum outro lugar
se a seção for executada agora. Vamos salvar isso e testar
isso no navegador. A seção else if agora
será executada. Como esta é a nossa primeira seção que resulta, então agora podemos fazer
o que quisermos em cada uma dessas seções, podemos mostrar e ocultar conteúdo dependendo da função do usuário. Podemos redirecioná-los
para uma área de conta. Podemos desativar recursos que o usuário pode
não ter permissão para acessar ou qualquer outra coisa que
você possa pensar. Também podemos usar várias
outras seções if também. Se quiséssemos verificar
mais do que essas três condições, também
poderíamos fazer o mesmo logo após a seção else if, colocada em uma segunda. Provavelmente está condicionado
de cima. Desta vez, verificaremos
se o user.role é igual ao autor. Se ele for colocado
em um log de console, salve isso e,
como seria de esperar, veremos o
mesmo resultado de antes já que temos o
assinante definido, que é uma correspondência
para esta seção. Mas se agora mudarmos
esta para ser a oferta, a seção if
agora é falsa e, em seguida a primeira seção se
também for falsa e nosso novo log de
console com
o texto do autor, agora
será executado
dentro do console. Finalmente, se nenhuma dessas seções, se ou então se as seções forem verdadeiras, então mudamos para ser
algo como usuário, agora devemos voltar para usar a
seção else na parte inferior.
9. A condicional switch: A instrução Switch é
uma maneira de fornecer quantos resultados precisarmos
com base em uma única condição. Também podemos fornecer
vários resultados com declarações
if e if
else , como
vimos anteriormente. Mas, como descobrimos, precisamos adicionar algo para
verificar para cada uma
dessas condições,
como quando verificamos coisas como a função do usuário para cada
uma dessas condições. Com uma
instrução switch, no entanto, apenas
testamos contra a
mesma condição para cada um. Apenas aqui com nossa variável de pizza
favorita. A instrução switch
logo abaixo, novamente, parece semelhante em sua
configuração a coisas como instruções if
vazias
e também for-loops. Em seguida,
passamos o que queremos verificar, como nossa variável de
pizza favorita. Então, lá dentro, configuramos os diferentes casos para lidar com
o que é a pizza favorita. Aqui teremos três casos
separados para lidar com o que fazer
para cada valor. Podemos ter quantos
desses casos quisermos. Vejamos o primeiro. Verificamos se a
pizza favorita é igual a pepperoni. Se for, então executamos
algum código dentro, como este log do console. Em seguida, fornecemos a
palavra-chave break para sair
da instrução switch
assim que tivermos uma correspondência e isso impedirá que todo
o resto do código e todas as demais
verificações abaixo sejam executadas. Esta é a mesma
palavra-chave break que usamos anteriormente
nesta seção para evitar que o navegador crie
um loop infinito. Isso continuará sendo executado
até que uma correspondência seja encontrada, mas se não puder ser encontrada, também
podemos adicionar uma cláusula
padrão também. Isso sempre será executado se não
houver outras correspondências. Para o projeto e
vamos dar uma chance a isso. Desta vez, estamos na seção de instruções
switch e dentro do arquivo inicial, teremos apenas um objeto de usuário
simples com a propriedade name
e também a função. Podemos configurar uma
instrução switch para verificar
a função do usuário e decidir se o usuário pode editar
algo em nosso site. Isso, podemos iniciá-lo em uma
variável chamada CANEdit. Portanto, o CanEdit será inicialmente definido como
um valor de false, para
que o usuário não receba nenhuma permissão
de edição por padrão. Em seguida, podemos usar uma instrução
switch para verificar a
função específica do usuário. Se o papel específico
do usuário for igual a um nível mais alto, como o
administrador ou até mesmo um editor, podemos definir CanEdit
como igual a true. Assim como
vimos nos slides, configure nossas
instruções switch e, em seguida,
passaremos a condição
que é user.role. Abra os aparelhos encaracolados, então podemos adicionar nossos
estojos dentro daqui. O primeiro caso
será o usuário. Este é apenas um usuário
conectado regularmente. Adicione o cólon.
Depois, adicionamos o que queremos fazer para
este caso específico. Bem, no nosso caso, queremos
manter o CANEdit como igual a false, já que eles não têm permissões de administrador ou
editor. Se esse caso
específico for verdadeiro, não
quero usar
a palavra-chave
break para sair do restante
dessas instruções switch. Essa é a primeira seção. Então vamos para
o segundo caso e este será um assinante. Isso apenas espelharia a
mesma condição acima. Podemos definir CANEdit ser igual a false. Adicione as palavras-chave de quebra. Esse é o nosso segundo
caso agora completo. O próximo, adicionaremos
um caso para o editor. E, como parece, o
editor é um caso em que
queremos permitir que o usuário
possa editar. Para isso, definiremos nossa variável canEdit como igual
a true e,
em seguida, sairremos da instrução
switch. Finalmente, o último caso
será para o administrador. No Admin,
queremos fornecer todas as permissões
necessárias para editar nosso site. Assim como acima,
definiremos CanEdit para ser também igual a true e, em seguida,
sair da instrução switch. Como vimos nos slides, também
precisamos adicionar
um caso padrão, que será executado se nenhum dos casos
acima for uma correspondência. Exemplo muito simples,
basta colocar em um log de console e diremos que a função do usuário não pode ser encontrada. Também definiremos CANEdit
como igual a false. Agora só precisamos fazer
um teste a isso. Quando
começamos aqui, temos a função de usuário
igual ao usuário. Isso deve definir CANEdit
como igual a false. Vamos testar isso
indo até o fundo, vamos colocar em um registro de console, colocar no valor de CANEdit. Veremos se isso muda
para cada um de nossos casos. Como sabemos, nenhum CANEdit
será igual a false, já que atualmente
temos a
função de usuário igual ao usuário. Vamos entrar nas
ferramentas do desenvolvedor para o console. É falso como esperado. Vamos verificar nossa
segunda condição
mudando a função
para assinante,
atualize e, como seria de
esperar, isso é falso. O terceiro é o editor, agora
isso deve ser verdade. Finalmente, podemos
testar o administrador. Isso também é verdade. Apenas para capturar a condição
padrão na parte inferior, devemos ver o log do
console e eles podemEdit ser igual a false se não tivermos uma correspondência para nenhuma dessas quatro condições. Vamos transformar isso para
algo completamente aleatório. Vamos apenas digitar qualquer papel
aleatório dentro daqui. Atualizar. Isso é falso e o log do console
agora é executado conforme o esperado. Apenas uma coisa a ter
cuidado se
tivermos vários casos correspondentes. Se eu tiver dois ou mais
casos que correspondam, o primeiro
caso correspondente será usado. Também como um atalho se
tivermos vários casos, assim como temos aqui, que
executam o mesmo código dentro. O usuário definirá,
podeEditar para ser igual a false e também o assinante. Esta é uma seção duplicada, a mesma para os dois últimos casos. Ambos os conjuntos podemEdit
para ser igual a true. Podemos encurtar
esse código um
pouco para torná-lo um
pouco mais simples. Para os dois primeiros, que
são exatamente os mesmos, o que podemos fazer é remover o
código do primeiro. Ambos os casos
se seguem imediatamente. Então esse código logo
depois será executado para cada um desses casos. O mesmo para esses
dois na parte inferior. Podemos mover o canEdit
e também o intervalo. Esses dois estão essencialmente
agora agrupados. Podemos apenas
testar isso e, se atualizarmos, ainda
veremos a
cláusula padrão sendo executada na parte inferior. Vamos tentar o editor.
Isso deve ser verdade. O administrador também é verdadeiro. O usuário deve ser falso. Finalmente, o assinante. É isso para as instruções
switch. Só uma coisa rápida
antes de seguirmos em frente. Se esquecermos de colocar uma palavra-chave break em qualquer
um desses casos, todos os
casos a seguir também serão executados até que uma pausa
seja finalmente encontrada. Por exemplo, se tivéssemos perdido uma cláusula break dentro desta seção,
podemos removê-la. Se tivermos uma correspondência
para o usuário ou o assinante, o CANEdit
ainda será igual a false,
mas executaria o
código logo abaixo
e, em seguida, substituiria o
CANEdit para ser igual a true. Vamos tentar isso. Temos o
papel igual ao assinante. Atualizar. Agora, o
assinante canEdit entrou em vigor, mas o
programa continuou indo para o editor e também
a seção de administração e causou uma substituição, então
CANEdit agora é igual a true.
10. Operador Condicional (ternário): Como alternativa às declarações
if-else
que vimos, o Javascript também tem um operador
condicional, muitas vezes chamado de operador ternário, já que é
composto por três partes. Como funciona,
assim como if-else, as principais razões pelas quais
ele é usado é oferecer uma alternativa simples de
linha única. Olhando para esse objeto de usuário, podemos querer verificar
a idade do usuário antes de permitir a entrada. O operador condicional
pode ajudar com isso. Está definido como uma pergunta. Aqui estamos perguntando se a idade
do usuário é maior ou igual a 18 usando
o ponto de interrogação. Antes, eu disse que o ternário é composto de três partes. A questão é apenas
esta primeira parte. A segunda e terceira
partes são o que
queremos fazer se a questão
for verdadeira ou falsa. Se for verdade, podemos fazer qualquer coisa, mas este exemplo simples só
tem o texto de enter. Se for falso, o que é
correto para este exemplo, o código após os
dois pontos será executado em vez disso. Vamos agora ir para os arquivos
iniciais e podemos dar uma olhada no
exemplo dentro de lá. Aqui temos um exemplo de como podemos usar uma instrução
if para verificar se um usuário é administrador que pode editar
algo em nosso site. O objeto de usuário tem
o papel de administrador
e, atualmente, definimos a funcionalidade
CANEdit igual a false. A instrução if está verificando
se a função do usuário, que está aqui,
é igual a admin. No nosso caso, podemos definir a variável
CANEdit como true, permitindo que o usuário
vá em frente e publique algo
como uma postagem no blog. Caso contrário, CANEdit
será igual a false, removendo todas as permissões
que eles possam ter. O que vamos
fazer é converter esse exemplo para fazer uso
do operador ternário, o que simplificará esse exemplo em
uma única linha. Assim como vimos
nesses slides, a primeira parte é
realmente fazer a pergunta. A pergunta
que queremos fazer é se o user.role é igual
à string de admin. Use um ponto de interrogação, seguido por nossos resultados verdadeiros e falsos. Se o usuário for igual a admin, queremos definir que este canEdit
seja igual a true, assim como fazemos
na seção true na instrução if-else. Defina CANEdit como igual a true
e, em seguida, separado por dois pontos, adicionamos a
declaração false onde dizemos que canEdit seja igual a false. Às vezes, dependendo das configurações ou dos plugins do editor de
texto, você também pode ver
essas duas
instruções encaixadas dentro dos colchetes. Isso é completamente bom. O que eu quero fazer
agora é
comentar ou remover as instruções
if-else originais, e então podemos salvar isso
e ir até o navegador, atualizar, e vemos que este
exemplo está definido como true. Isso é verdade porque o
user.role é igual a admin. Mas se mudarmos isso
para ser outra coisa, vamos tentar assinante, você deve atualizar isso para
ser o valor de false. Também podemos encurtar esse
exemplo ainda mais atribuindo diretamente
o resultado
desse operador ternário
a essa variável. O que queremos dizer com
isso é, em vez atribuir podeEditar para ser
igual a verdadeiro ou falso, quando cortar o
operador condicional completo daqui, podemos remover a atribuição
inicial de false, colar isso em. Agora, em vez de
definir nossa variável, o que fazemos é simplesmente definir o valor
verdadeiro como verdadeiro e o valor
falso como igual a false. Agora, o
resultado verdadeiro ou falso para isso será atribuído
diretamente à
nossa variável CANEdit. Vamos
testar isso mais uma vez. Atualmente, temos
esse conjunto como falso, mas se mudarmos isso de
volta para ser o administrador, isso agora é igual a ser verdadeiro. Tanto o
operador condicional quanto a versão if-else são
perfeitamente válidos para uso. O operador condicional,
como acabamos de ver, geralmente
é mais curto e
colocado em uma única linha. Alguns argumentam que uma declaração
if-else é mais clara e mais legível, mas no final, é sua
escolha que você deseja usar e qual você prefere.
11. Tipo Coersão & Conversão: Nos próximos vídeos,
vamos cobrir algum tipo e também algumas coisas verdadeiras
ou falsas relacionadas, o que pode lhe dar alguns resultados
estranhos ou inesperados. Estar ciente disso
pode ajudá-lo a entender coisas como por que e se instrução não está
sendo executada corretamente, e também economizar muito
tempo na depuração. A primeira é a coerção do tipo. Já sabemos
sobre tipos como objetos, cordas e booleanos. coerção de tipos está relacionada
à forma como os valores dos tipos de dados são convertidos
para outros tipos de dados. Olhando dentro da pasta de
lições, que é coerção de
tipo e comparação, salte para o index.html, onde
temos um exemplo simples. Temos duas variáveis no topo com números e
, em seguida, vamos adicionar ambas
juntas e
armazená-las dentro do total. Uma coisa a notar entre esses dois números
é que o primeiro é enrolado dentro dessas cotações então, tecnicamente, isso é uma string. O segundo é um número,
como você esperaria. Mas o que você acha que
acontece quando
adicionamos ambos juntos? Se estivéssemos adicionando strings, talvez saibamos
o que esperar, porque isso pode ser
combinado para fazer uma frase ou uma palavra. Se também estivermos
adicionando dois números, esses dois números seriam
adicionados para obter um novo total. Mas aqui, como estamos adicionando
uma string e um número, o que você acha que acontecerá? Bem, em vez de
causar um erro, o JavaScript foi projetado para escolher um tipo de dados para
converter automaticamente. Isso é chamado de coerção. Mas este exemplo pode
optar por converter para que sejam ambas cadeias de caracteres ou ambos números. Bem, não vamos adivinhar. Vamos salvar isso e
entrar no console e ver exatamente o que
vai acontecer. Entre na guia do console e atualize e vemos
o valor de 72. O valor de 72 significa que isso está sendo
convertido em uma string porque temos o valor de sete seguido
pelo valor de dois, em vez do valor de nove, que aconteceria se estes fossem convertido
para ambos para números. Essa conversão aconteceu automaticamente para nós e
isso pode ser
referido como implicitamente e essa conversão implícita
é o que é coerção. Não deve ser confuso,
mas algo semelhante é a conversão de tipo. Isso funciona de forma semelhante à
coerção convertendo um valor de um
tipo de dados para outro. Mas também podemos fazer isso
sozinhos manualmente. Se quiséssemos que isso fosse
convertido em um número manualmente, temos uma
função numérica disponível. A maneira como podemos usar isso é
cortar nosso número um,
que é uma string. Podemos acessar uma
função numérica e, em seguida, colocar dentro do que queremos
converter em um número. Aqui nós convertemos uma
string para ser um número. Agora, se salvarmos
isso, devemos ver o valor de nove
no console, o que
significa que
ambos atraem como números. Para
recapitular, a coerção acontece de forma implícita ou automática. conversão de tipos também pode
acontecer manualmente, assim como estamos vendo
com essa função numérica. Às vezes, essas palavras são
usadas de forma intercambiável, mas essa é a
linha oficial em ambas. Se você quisesse,
também poderíamos fazer o contrário. Em vez de converter
este em um número, poderíamos converter o
segundo para ser uma string. Fazemos isso com a função
string. Passe o número que
você deseja converter em uma string e isso
retornaria ao valor da string de 72. Por esse motivo, pode
ser bom sempre converter dados
recebidos para serem exatamente o tipo de dados que
queremos que sejam. Se, por exemplo, estamos recebendo
dados de terceiros, como um servidor ou uma API, podemos eliminar bugs e erros certificando-se de que nosso tipo de
dados esteja correto. Por esse motivo, você
pode ter ouvido falar de ferramentas como TypeScript, que nos impõe a
declarar o tipo de dados que você
deseja usar antecipadamente, o
que pode, portanto, eliminar
quaisquer erros em nosso código. É assim que as coisas funcionam
com o operador plus, mas os outros operadores também
podem nos
dar resultados esperados também
após a aplicação da coerção. Também podemos ver essa
coerção em ação com o operador
maior ou
menor que. Veja isso mudará
o log
up do console com o valor ou os resultados do número um são
maiores que o número dois. Vamos ver o que acontece.
Obtemos o valor de true. Isso pode parecer um pouco
estranho porque aqui dentro do log do console, ainda
estamos comparando uma
string com um número. Mas neste caso,
o JavaScript está
comparando-os como se ambos
fossem números. Esse é um comportamento louco
para pessoas que estão acostumadas com outras linguagens de
programação, o que é fortemente digitado. O que significa que os dados
são restritos a um determinado tipo e
não são convertidos. Embora essa coerção
aconteça nos bastidores, às vezes os exemplos
que veremos têm algum comportamento bastante sensato ou
previsível. Mas muitas vezes vemos alguns resultados
estranhos assim. Também podemos ver alguns resultados
estranhos quando se trata de
incrementar também. Veja isso, em vez de ter
uma constante para nossa string, o que vamos fazer é
mudar isso para ser deixado. Portanto, podemos atualizar
esse valor de número um. Vamos fazer isso logo abaixo. Vamos acessar nossa variável número
um e depois usar plus plus para incrementar
isso pelo valor de um. console registra o valor da nossa variável e vamos ver o que
acontece dentro do console. Atualize e vemos
o valor de oito. Isso pode parecer estranho
porque sabemos que o número um está inicialmente
definido como uma string. Tecnicamente, não
devemos ser capazes aumentar isso
pelo valor de um, como faríamos com um número. O que acontece
nos bastidores com coerção é que o número um é convertido
em um número, portanto, podemos usar o incrementador. Acho que você veria o valor
de oito no console. Como outro exemplo, imagine que
isso também era um array. Se cercarmos isso dentro dos colchetes
contendo nossa corda dentro, o que você acha que
aconteceria agora no console? Ainda incrementamos
esse valor. Vamos dizer isso e ver o que
acontece dentro daqui. Atualizar. Mais uma vez, isso não
faz sentido. Ainda obtemos o valor de oito, mas esse é o
mundo do JavaScript. E se
comentássemos esse
plus, mais e adicionamos diretamente
um valor a essa matriz. Digamos que mais 2, salve, atualize e vejamos
o valor de 72. Novamente, isso pode
parecer um comportamento louco, mas o que aconteceu
nos bastidores, como você deve ter adivinhado, é que isso foi convertido em uma string. Se você
quisesse provar que isso era uma string, ou se quiséssemos verificar novamente, também poderíamos usar typeof
dentro do log do console. Vou digitar o suco
antes do nosso número um, salvar isso e isso
emitirá o tipo de dados
que é uma string. Também aqui está
algo muito estranho também. Esta é uma string como
acabamos de ver, mas o que você
acha que aconteceria se
reintroduzirmos os incrementos? Bem, vamos descomentar isso, salvar e atualizar, e
agora estamos de volta a um número. E se também removermos o typeof e pudermos ver
o que acontece quando
somamos os sete e
os dois e, em seguida, também usamos o incremento.
Vamos salvar isso. Isso agora nos dá o resultado do valor numérico de 73. O que significa que o que acontece originalmente para o número um é que o nosso era 7 e 2 são adicionados
para criar uma string de 72, assim como vimos anteriormente. Isso ainda é uma string,
mas quando chega à próxima linha, como também vimos anteriormente
quando usamos o plus plus, ele adiciona o
valor de 1, dando-nos o valor de 73
dentro do console. Além
de toda essa loucura, o operador de igualdade
também introduz um novo mundo de coisas
para tomar cuidado com dois. Por exemplo, em nosso log do console, podemos verificar se 1 é igual
a true. Isso é verdade. Mas e se
convertermos isso para um número diferente, como 11? Isso agora nos dá
o valor de false. Apenas para recapitular, o valor
de um era igual a verdadeiro, mas o valor de 11
era igual a false. Vamos tentar mais um
número, como dois, atualizar e esse também é
o valor de false. Mas essa é outra
peculiaridade do JavaScript, mas pouco antes de explicarmos, eu só quero adicionar alguns
comentários na parte inferior. Então, verdadeiro é o número 1 e
0 é igual a false. Para entender isso melhor, precisamos entender
que, ao usar o duplo igual,
assim,
esta é a
igualdade solta, o que significa que
não estamos verificando nenhum tipo de dados
improvável triplo igual, que já vimos antes. Tudo o que estamos fazendo é
verificar se dois valores são iguais, independentemente
do tipo de dados. Como estamos comparando um número aqui com um booleano
à direita, não
estamos verificando
por tipos iguais. O JavaScript converterá
usando coerção e,
neste caso, converte o
booleano em um número. Assim como escrevemos antes, o número um é
igual a verdadeiro e o JavaScript usará o número
zero para ser igual a falso. Podemos testar isso no log
do console. Podemos verificar se o valor de um é igual a falso,
o que não é verdadeiro. Ele deve nos dar o valor
um falso dentro do console. No entanto, se mudarmos
para ser o valor zero, zero é igual a falso, assim como
vimos abaixo e isso deve resultar em verdadeiro. Isso é muita
peculiaridade de se aceitar e também não
termina aí. O JavaScript tem tantas
dessas coisas que você
precisa tomar cuidado. Não espero que você se lembre de todos
eles nesta fase. Mas saber que esse comportamento existe e dá
uma boa vantagem para
saber onde procurar se você está encontrando bugs
dentro do seu código.
12. E-mail: &: Em muitos desses exemplos
nesta seção e na codificação JavaScript em geral, verificamos se um valor
é verdadeiro ou falso. Se for verdade, executamos
algum código
e, se for falso,
fazemos outra coisa. Mas não é apenas
um valor booleano verdadeiro e falso,
que podemos usar, como vimos no
último vídeo, outros valores também
podem avaliar como verdadeiro e falso também. Como zero é
avaliado como falso, e o número
quer ser igual a verdadeiro. Também há muitos
outros exemplos, como uma string
de texto é verdadeira, e uma string vazia é
o oposto de false. Isso é chamado
de verdade ou falsidade. Verdade é quando um valor
é avaliado como verdadeiro, como nossa cadeia de
textos estar presente, e falseia é quando um
valor é avaliado como falso, como nossa string vazia
ou nosso número zero. Entre em nosso editor e
podemos dar uma olhada em alguns exemplos dentro
do nosso script vazio. As instruções if serão executadas
não apenas para um valor booleano verdadeiro, mas também qualquer outro
valor verdadeiro também. Digamos que,
primeiro configurando uma instrução if-else vazia e, em
seguida, dentro daqui, vamos colocar em
registros de console muito simples. Para a primeira seção, vamos avaliar
algo como verdadeiro, passaremos o texto do verdadeiro V. Na seção L,
faremos o contrário. Adicionando o texto de falsey. Claro, isso não será executado
no momento porque não
temos nenhuma condição
dentro da instrução if. Mas vamos começar com
o que já sabemos. Anteriormente, analisamos os
valores de zero e um, onde o valor de zero
é igual a falso. Isso seria
avaliado para falseia, no entanto, o oposto é
verdadeiro com o valor de um. Além disso, podemos testar a string que você mencionou pouco antes. Temos uma string com
alguns conteúdos dentro, como o texto de hey. Isso também será
avaliado como verdadeiro
também , já que temos algum
valor dentro da string. Mas se nós removêssemos isso
e tivéssemos uma string vazia, isso seria avaliado em JavaScript
o valor de falsey. A coerção sobre a
qual falamos está acontecendo nos bastidores, e valores como nossos
números zero e um e também esse valor de string aqui está sendo convertido para ter um equivalente
booleano. Podemos determinar se
coisas como essas
instruções if devem ser executadas em não. Os valores falsamente, como
seria de esperar, geralmente
são
valores vazios, como zero, que acabamos de ver, e também essas strings vazias também. Vamos dar uma olhada em
mais alguns exemplos, como não. Isso também é falsey. Indefinido, isso
também deve ser falsado também. Geralmente, qualquer coisa que
não tenha um valor presente, então a palavra false. Como seria de esperar, isso
também seria avaliado como falsey. Finalmente, observe o
número, que é NaN. Isso também é falsey também. Podemos considerar praticamente
todo o resto como verdadeiro,
como as strings que
acabamos de ver , matrizes, números diferentes de
zero e, de fato, qualquer tipo de objeto,
como uma função, matriz ou um objeto real
resultará em ser verdadeiro. Isso também é verdade,
independentemente de usarmos o construtor ou um
tipo literal, assim. Poderíamos usar o construtor. Analisamos coisas
como nova matriz e novo objeto no
passado. Isso será verdade. Vamos tentar um
construtor de funções que também
será verdadeiro
e, finalmente, o objeto. Da mesma
forma, se quisermos
usar um construtor
como este e usarmos isso literalmente como
fizemos mais comumente
nesses vídeos, como criar uma matriz
com valores diferentes dentro. Isso seria verdade assim
como o construtor, além de colocar em um
objeto em uma fonte literal também. Essa coerção, combinada com a
compreensão de como os valores são convertidos para serem
verdadeiros ou falseados, é uma coisa boa de se
entender dentro do JavaScript,
pois pode realmente
ajudá-lo a
evitar problemas no futuro e também ajuda
com problemas de depuração também.
13. Corrente opcional: Este vídeo vai se concentrar em algo chamado encadeamento
opcional, que foi introduzido em
JavaScript na ES2020. Como já sabemos,
precisamos ter acesso a alguns dentro
de um objeto, como nosso nome e
também nosso papel de administrador. Além disso, como sabemos, podemos ir
ainda mais fundo acessando objetos aninhados dentro
de um objeto também. O que acontece quando as propriedades dentro dessa cadeia não
estão lá? Veja alguns exemplos de
encadeamento na seção de eventos, onde acessamos
o objeto de evento. Em seguida, fomos mais fundo em
propriedades como o destino, o nó pai, os filhos
e, em seguida, no valor do texto
interno. Se, em algum momento dessa cadeia,
uma propriedade não existir, nós receberíamos um erro. Mas isso não é uma coisa ruim, pois devemos ter erros
se fizermos algo errado. Mas e se
a propriedade só
às vezes estiver lá
e às vezes não? Um exemplo disso
é o que estamos
usando já dentro
do script. Ele terá o usuário atual
que está definido como um objeto de usuário conectado e temos todas
as informações necessárias, como o nome e a função. Portanto, quando vamos
para as instruções if e verificamos se a
função do usuário é igual a admin. Sabemos que isso deve funcionar
sem erros, mas com os usuários, embora nem
sempre os
tenhamos que estar conectados. O usuário atual nem
sempre está configurado para ser um
objeto como esse. Por exemplo, se o
usuário não estiver conectado,
no lugar desse objeto de usuário poderemos ver o valor de null. Agora, se tentarmos executar
a instrução if, não
teremos acesso
à propriedade.role. Portanto, vamos ao console e
ver o que acontece. Dentro do console, vemos
essa mensagem de erro vermelha, que nos diz que há um
problema com a leitura da nossa função. Isso acontece porque o usuário
atual não é mais um objeto que contém
a propriedade role
, causando um erro. Mas ainda precisamos de uma maneira de manter essa função ativa dentro
da instrução if. Mas depois que
o usuário fizer login. É aqui que entra em jogo o
encadeamento opcional. O que podemos fazer é
inserir um ponto de interrogação para declarar que a propriedade pode
nem sempre estar lá. Nós adicionamos isso apenas antes.role. Agora, se salvarmos isso e atualizarmos em vez do
erro dentro do console, já que agora ele é
avaliado como false, a seção else agora será
executada dentro do console. O que acontece dentro daqui é que chegamos às declarações if. Em seguida, o JavaScript
lerá o usuário atual, que é o valor de null. Portanto, ele sabe não ir mais longe com o
resto da nossa cadeia. Agora ele ignora o
erro e, em vez disso retorna um
valor indefinido, que podemos verificar dentro
do log do console. Atualmente, sabemos que
a seção else está sendo executada porque
vimos o valor de false. Mas, em vez disso, o que
podemos fazer é acessar o usuário atual, um ponto de interrogação, já que isso
nem sempre
estará lá no encadeamento
opcional. Em seguida, podemos adicionar o
valor da função. Se salvarmos isso e
atualizarmos, agora podemos confirmar que
recuperamos o valor de indefinido. Isso é realmente útil
se soubermos antecipadamente que uma determinada propriedade de objeto pode
ou nem sempre estar lá. É comum que
objetos como esse cresçam
ao longo do tempo e nem sempre sabemos como nosso aplicativo
pode se desenvolver no futuro. Talvez seja necessário adicionar recursos
extras ou coletar mais informações. Esse encadeamento opcional
pode evitar erros. Por exemplo, no
futuro, talvez precisemos adicionar mais informações sobre a fonte de inscrição
do usuário. Poderíamos adicionar um
objeto aninhado dentro, assim,
retornaremos ao objeto usuário. Vamos restabelecer o
nome e a função. Em seguida, um segundo objeto aninhado dentro do qual vou
chamar os dados de inscrição, este será um objeto aninhado dentro.
Vamos colocar na data. Mas agora uma corda vazia está boa. Isso realmente não importa e confirmou ser igual a verdade. Então, ainda mais adiante, à medida que nosso aplicativo se desenvolveu ainda mais, talvez
precisemos nos
aprofundar ainda mais nesse objeto. Por exemplo, podemos querer
coletar mais detalhes sobre a fonte de inscrição do usuário
dentro desse objeto. Também podemos adicionar a fonte, que também é um objeto em que vimos o URL
da fonte de inscrição. Novamente, este é apenas
um exemplo para que
possamos adicionar qualquer coisa dentro
da string no navegador do
qual o usuário veio. Agora precisamos de cadeias mais longas para acessar essas informações aninhadas. Se acabarmos de remover essas instruções
if else, e simplificaremos isso
com um log de console. Precisamos primeiro acessar
os objetos do usuário, que era o usuário atual. O objeto dentro do qual
foram dados de inscrição, então.signupdata, Por exemplo, se
quiséssemos
acessar o navegador, também precisaríamos entrar
na fonte pouco antes disso. O objeto de origem e,
em seguida, o navegador, atualize e esse agora deve
ser o valor do Chrome. Mas lembre-se, neste exemplo, tudo isso foi adicionado ao
objeto em um estágio posterior. Alguns dos usuários de
inscrição anteriores não terão os dados de inscrição
associados a seus objetos. O que podemos fazer, podemos simular isso comentando
esta seção, o que causará um erro, como vimos antes. Novamente, o encadeamento opcional
pode nos ajudar com isso, permitindo que nosso código falhe silenciosamente em vez exibir um erro
dentro do console. Dentro dos
dados de inscrição não
teriam mais acesso à
fonte ou ao navegador. Podemos adicionar o
encadeamento opcional aqui, atualizar e agora vemos
os resultados de indefinido. Erros gerais são bons para
nos informar quando
fizemos algo errado. Mas em casos como este, sabemos que temos uma propriedade que pode ou não estar lá, encadeamento
opcional pode realmente nos
ajudar, falhando silenciosamente e, portanto,
permitindo-nos lidar com o
erros nós mesmos.
14. Criando e modificando novos objetos: Praticamente qualquer coisa que
possamos pensar tem certas propriedades pode ser um bom caso de uso para um
objeto em JavaScript. Por exemplo, uma pessoa pode ser um objeto e as propriedades
podem ser o nome, idade, altura e
qualquer outra
informação que queremos
dar a uma pessoa. Um computador também pode
ser um objeto com propriedades
como a marca, o modelo, a CPU, o ano de fabricação
e também a memória. Quando pensamos em
objetos como esse, os casos de uso se tornam enormes. Assim como acontece com matrizes,
existem diferentes maneiras construir um objeto, e o estilo que vimos
até agora é chamado de literal do
objeto. Isso é usado para
criar e definir um novo objeto com
as chaves, que inclui algumas propriedades, assim como temos aqui. Para os arquivos iniciais. Entre no arquivo desta lição, que é o construtor de objetos, e abra isso
dentro do navegador. Como mencionado anteriormente
com os slides, temos duas maneiras
diferentes de criar um objeto. Temos a abordagem literal, assim como usamos anteriormente, e também temos uma abordagem
chamada construtor. O construtor não é novidade. Nós analisamos isso
anteriormente com matrizes. Normalmente, criamos matrizes usando uma abordagem literal, como uma matriz de pizza, e configuramos nossas propriedades dentro desses colchetes. Além dessa abordagem
literal, também
podemos criar uma matriz
usando o construtor. Por exemplo, se quiséssemos
uma variedade de ingredientes, podemos configurar isso usando a nova palavra-chave
seguida de array. Essa é uma abordagem literal
e é assim que podemos criar uma matriz vazia com
o construtor. Em seguida, podemos acessar
nossa matriz vazia e adicionar novos valores com métodos como push para adicionar
qualquer novo valor a essa matriz. Da mesma forma que
nossos arrays aqui, também
podemos fazer o mesmo
para outros objetos. O que vou fazer
é comentar essa abordagem literal e recriar isso usando o construtor de
objetos. Primeiro de tudo,
criaremos uma nova variável chamada user para imitar os objetos acima e definir
isso igual a um novo objeto. Esse novo objeto será um invólucro
de objeto vazio
e, em seguida, podemos
avançar e enviar novas propriedades para esse objeto. Fazemos isso acessando
nossa variável. Em seguida, podemos definir o nome
da propriedade diretamente
para o nosso objeto. Primeiro, vai ser a
chave, assim como temos aqui. Em seguida, atribuímos isso
a um determinado valor. Isso é igual a uma
série de Chris. Então o segundo é para
o sobrenome, também uma string. A terceira foi
a ocupação. Em seguida, temos o booleano
logado de true for user.logged.in. Este é um booleano, então
não precisamos das citações. Então, finalmente, também podemos atribuir uma matriz a todas as propriedades de alimentos. Só vou copiar esse
array logo acima. Podemos testar isso
agora está funcionando fazendo um log de console para
o valor do usuário
e, em seguida, entrar nas
ferramentas do desenvolvedor para o console. Há nosso objeto com todas as nossas propriedades aninhadas no interior. Também podemos acessar propriedades
individuais
usando uma notação de ponto. Isso funciona exatamente como fizemos
com a abordagem literal. Podemos usar user.first. Isso imprimirá nosso primeiro
nome dentro do console. Assim como essa notação de pontos, assim como usamos anteriormente, também
podemos acessar
nossas propriedades com a notação de colchetes também. O que precisamos fazer é
cercar o nome da nossa propriedade nesses colchetes,
remover o ponto. Isso também precisa ser uma string. Ambos dão
exatamente o mesmo resultado. Se quiséssemos,
também poderíamos atualizar diretamente uma de nossas propriedades
também, então user.first. Em seguida, podemos reatribuir isso ou atualizar isso para
ser um novo valor. Em seguida, podemos
imprimir isso no console. Isso nos dará
nosso valor atualizado. Como nota paralela, se acidentalmente
tivermos mais de uma propriedade
que é uma duplicata, assim como aqui onde
temos o primeiro nome duas vezes em nosso código, desde ES 2015, o último ocorrência será usada em vez de
lançar um erro. Além disso,
também podemos excluir qualquer uma
dessas propriedades usando o operador de exclusão
JavaScript. O que precisamos fazer
é adicionar delete, que aponta nosso primeiro
nome, salvar isso e atualizar, e apenas
imprimiremos o objeto completo do usuário. Abra isso, e
isso agora removerá o primeiro nome do
nosso objeto de uso. Essas são duas
maneiras diferentes de criar um objeto em JavaScript. Pessoalmente, prefiro a abordagem literal
que tínhamos no
topo , pois para mim parece mais
limpo e simples de usar. Mas isso se resume completamente
à sua preferência pessoal. Nos próximos vídeos,
abordaremos como configurar uma função semelhante a um modelo para
criar vários objetos.
15. Função construtora de objetos: Ótimo. Agora estamos cientes de duas maneiras diferentes de criar objetos
dentro do JavaScript. Se você entrar no arquivo
desta lição, que são funções de
construtor de objetos, veremos que temos apenas um
script vazio dentro daqui. As duas maneiras diferentes pelas
quais criamos objetos é criar uma nova
variável assim, e então podemos
adicionar nossas propriedades diretamente dentro
das chaves. Alternativamente,
também podemos usar um novo objeto, que é a
abordagem do construtor e isso nos dará um objeto vazio em
nossas propriedades também. Ambas as
abordagens funcionam bem, mas também estão limitadas a criar
apenas um único objeto. Seria mais útil
se pudéssemos ter um modelo de objeto para que possamos criar vários objetos
com base nisso, cada um mostrando as mesmas
propriedades e métodos. Também podemos fazer isso com
a função de construtor. O que
faremos é remover isso e criar uma nova função de
construtor. Também é uma boa prática nomear essas funções de construtor
com uma letra maiúscula. Usamos em nosso exemplo de usuário, é um U maiúsculo e, seguida, criamos o resto
da nossa função. O objetivo desta função de
construtor para nosso usuário é criar vários usuários com base
nesse modelo. Dentro da nossa função, também
vamos passar alguns valores que
precisaremos dentro daqui. O primeiro, vamos
manter isso bem simples, apenas
dizemos primeiro,
sobrenome e ocupação. Voltaremos a essa
função em apenas um momento. Mas antes de criarmos
um novo objeto, assim, então usamos a nova palavra-chave e, em seguida,
a função objeto. Mas agora, em vez de criar
um novo objeto vazio, queremos criar uma nova
instância do nosso usuário. Em vez de novo objeto,
diremos que o novo User maiúsculo U, onde vamos passar
os valores reais que você deseja usar
para nossa função. Precisamos passar o
primeiro nome, o último e a ocupação e
esses serão
os três valores reais
que precisamos para nosso usuário. Vamos dizer Chris, o sobrenome, e finalmente a ocupação. Também podemos duplicar isso
quantas vezes eu quiser,
porque, como mencionamos, todo
o objetivo de criar
essa função de construtor é agir como um
modelo para criar quantos objetos quisermos. Criamos nosso segundo,
tem um nome diferente, e também oito
ocupações diferentes também. Com ambos os novos usuários, também
podemos armazenar isso
dentro de constantes ou variáveis para que possamos
acessá-los mais tarde. Então diga const chris
igual ao nosso, e então o
segundo é igual a homer. Ótimo. Agora, o que
vamos fazer é registrar o valor de qualquer
um desses novos usuários. Colocando um log de console, o valor de homer e, em
seguida, salte para o console. Como você pode ver,
temos um objeto de usuário. Mas se
abrirmos isso, não temos nenhuma propriedade dentro daqui. Tudo o que temos é um objeto de usuário
vazio. Isso pode ser esperado porque nossa
função de construtor que
criamos anteriormente está vazia. Não temos nenhum código
dentro das chaves. Recebemos os valores
dentro da função , mas não estamos realmente fazendo nada com eles ainda. Para fazer isso, precisamos
definir algo para ser igual a esses três valores. Precisamos definir algo
para ser igual ao nosso primeiro, algumas coisas para ser
igual à nossa última e algo para ser
igual à nossa ocupação. Mas o que fazemos para
transformá-los em nossas propriedades de objeto? Bem, para definir uma propriedade, precisamos usar
a palavra-chave this. Para entender a
palavra-chave um pouco melhor, quero
levá-lo rapidamente de volta a um arquivo anterior
nesta pasta do projeto. Se voltarmos para o número
três, que é funções, e depois o número cinco, que
é uma função ou um método, salte para esta
página de índice aqui. Dentro daqui, você pode
se lembrar de que criamos um objeto chamado cheque recipes. As receitas de verificação tinham
algumas propriedades como o
número atual de receitas, o máximo de receitas e também um método
chamado receitas deixadas, que deduziu o número
atual de receitas de o máximo. Lembre-se de que um método é apenas uma função
localizada nesse objeto. Dentro desse método,
fizemos uso da palavra-chave, this para acessar outras
propriedades desse objeto. Acessamos as receitas máximas, que estão nesse objeto e
também as receitas atuais também. A palavra-chave this pode ser uma coisa complexa de se
entender em JavaScript, mas nessas circunstâncias, ela simplesmente apontará para o
objeto que possui aqui. Ou seja, podemos acessar qualquer uma
das outras propriedades
dentro desse objeto. Com isso em mente, de volta
ao nosso arquivo atual, agora
podemos adicionar todas as propriedades exatamente
da mesma maneira usando a palavra-chave, seguida
pelo nome da propriedade. Para o primeiro dirá isso.FirstName e também o
mesmo para os outros também, this.LastName e,
finalmente, isso.ocupação. Isso agora construirá
nossos dois objetos de usuário com as propriedades
que passamos para dentro. Salve isso e, com
nosso log do console ainda no lugar, atualize. Nosso usuário Homer agora está
construído corretamente e também podemos duplicar
isso para nosso primeiro usuário. Isso agora nos dá
dois objetos exclusivos, que são ambos baseados
no mesmo modelo. Se precisarmos adicionar
propriedades e métodos extras, também
temos algumas opções. Podemos adicioná-los diretamente a
um de nossos objetos como este. Assim como olhamos
no vídeo anterior, podemos acessar nossa
variável, como homer. Podemos dizer vidas e definir
isso igual ao nosso valor. Também podemos adicionar métodos
aos nossos objetos também. Podemos acessar nosso objeto, que é homer e,
em seguida, podemos dar isso um nome de propriedade
que será o nome
completo e definirá isso
igual a uma função. A responsabilidade
dessa função será
retornar uma nova string, que é o primeiro nome
adicionado ao segundo nome,
então retorne nossa string, então retorne nossa string, que é homer.FirstName, adicione um espaço vazio no meio e, em seguida, adicione no
final homer.LastName. Vamos
tentar isso. Primeiro de tudo, vamos tentar a propriedade lives. Adicione isso ao console, atualize e obtemos o
valor de Springfield. Em seguida, podemos tentar nosso
método, que foi o nome completo. Atualize o navegador. Opa, temos um valor indefinido, então vamos
verificar isso. Temos Homer.FirstName,
tudo bem. Apenas um erro ortográfico no topo
do ar,
então vamos mudar isso. Agora vemos que este é
Homer Simpson isso , então isso está funcionando
completamente bem. Mas eles só são adicionados
aos nossos objetos únicos. Estes são adicionados apenas a variável Homer
alta. Se tentarmos
acessar em nossa
variável Chris e tentar
isso no console, veremos um erro dentro daqui. Essa abordagem
só é útil se você quiser alterar um objeto
específico. Se quisermos fazer com que eles se apliquem a todos os objetos criados, precisamos colocá-los
na função de construtor na parte superior. Então, antes de tudo,
precisamos passar
a propriedade de vidas para nossa função e então podemos adicioná-los aos
nossos dois objetos abaixo. Chris, valor do Reino Unido e Homer, o valor de Springfield. Também precisamos modificar
nosso corpo de função. Vamos duplicar isso e
diremos isso.lives é igual ao valor das
vidas que você passa. Também precisamos passar
o método também. O método
sempre será o
mesmo, apenas usando o
primeiro e o sobrenome existentes. Vou apenas cortar e
colar isso em nossa função. Corte isso, cole isso
em nossa função. Desta vez, vamos
remover homer, substituir homer por
, esta palavra-chave. Também o mesmo dentro do
nosso corpo de função também. Lembre-se, assim como
o exemplo anterior no vídeo anterior, essa palavra-chave apontará para qualquer outra propriedade
nesta função de usuário. Finalmente, também podemos
remover homer.lives. Não precisamos mais
disso, então agora podemos salvar isso e atualizar. Agora, o método de nome completo funciona
para os dois objetos.
16. Protótipos de Objetos: Se você não
entendeu bem o papel
do protótipo nos primeiros vídeos,
espero que agora
vê-lo em ação com nossos próprios objetos possa ajudar a
fazer algumas coisas clicarem. No projeto inicial, começamos com a seção de
protótipo de objeto com o mesmo exemplo
do vídeo anterior. Temos uma
função de construtor para criar modelos ou blueprints. Isso significa que podemos
criar vários objetos com as mesmas propriedades
e métodos disponíveis. Em seguida, analisamos como
adicionar propriedades e métodos, tanto para um único
objeto quanto para
a função para que eles se apliquem
a todos os novos objetos criados. Além de adicionar à função de
construtor, também
podemos adicionar diretamente
ao protótipo também. Mas antes de fazermos
isso, vamos primeiro atualizar o que sabemos
sobre o protótipo. Na parte inferior, estamos fazendo um log de console com
o valor de homer, que criou um novo
objeto de usuário do nosso construtor. Se abrirmos isso dentro
do navegador e entrarmos Ferramentas
do Desenvolvedor
para o Console, e vamos dar uma olhada no
que vemos aqui dentro. Atualize e vemos nosso usuário. Vamos abrir isso. Ele
contém nossas propriedades. Temos o primeiro
nome, o sobrenome e todos os valores que
você vê na parte inferior. Então, na parte inferior,
temos esse protótipo, que é um link para a cadeia de
protótipos. Abra isso. No interior, podemos ver nosso próprio construtor,
que é nosso usuário. Além disso, um
segundo protótipo de objetos. O primeiro protocolo, que é
o que está no topo aqui, aponta para nossas próprias adições
de protótipo, que veremos em breve. Então, o segundo
que acabamos de abrir, isso agora tem muitas
coisas dentro daqui, que não nos adicionamos. Temos coisas como
ValueOf, toString. Essas não são coisas que
nós mesmos criamos. Lembre-se, de anteriormente, os objetos
JavaScript
herdam propriedades e métodos de objetos pai. No topo dessa cadeia de
herança está o objeto. Vamos agora registrar isso no
console para referência. Apenas com o Homer farei
um segundo log do console com o valor do objeto. Agora vamos salvar isso e
atualizar o navegador, deixando-nos com o tipo de objeto
principal ao lado de nosso próprio objeto doméstico. Esse primeiro valor de objeto
é um objeto vazio, que você pode ver se
você abrir isso. Está vazio em termos de
não ter propriedades de valores
dentro, como temos aqui. Mas o objetivo
desse objeto de nível superior, mesmo que esteja vazio, é conter as
propriedades e métodos mínimos que passam para outros objetos através
da cadeia de protótipos. Podemos ver isso se
abrirmos isso. Isso contém todas essas propriedades e
métodos aos quais agora podemos ter acesso por meio de
nossos próprios objetos criados. Se agora abrirmos
nosso próprio objeto doméstico, vá até o protótipo. Em seguida, o segundo
protótipo aqui, você pode ver que isso herdou as mesmas propriedades e métodos de nossos objetos de nível
superior. Isso agora significa que eles
estão agora disponíveis para uso em nossos próprios objetos personalizados. Como vimos anteriormente, é por isso que coisas
como matrizes personalizadas têm métodos disponíveis, como para cada push e pop. Na verdade, não criamos
esses métodos nós mesmos. Mas, em vez disso, eles são herdados
da cadeia de protótipos. Todos os raios podem
fazer uso deles. Não devemos adicionar nossas próprias
propriedades e métodos a objetos que
não criamos nós mesmos, mas podemos adicioná-los ao nosso
próprio construtor personalizado, como esse usuário. Podemos fazer isso acessando a propriedade protótipo
neste usuário. Logo abaixo disso. Vamos
criar algum espaço. Acesse nosso construtor de usuários. Em seguida, o protótipo. Podemos definir uma nova propriedade
aqui, então qualquer valor. Isso pode ser outros
tipos de dados, como cadeias de caracteres, números ou até mesmo métodos. Também podemos remover
o primeiro objeto, deixando nosso segundo objeto
homer no lugar. Atualize, abra isso, pule para o protótipo. Agora, vou abrir
esse objeto protótipo. Também vemos a propriedade personalizada,
que acabamos de definir. Vemos que cool não é colocado
no objeto original ao lado do primeiro nome, por exemplo. Mas se tentarmos acessá-lo,
legal, então seja procurado
na cadeia de protótipos. Se não estivesse na nossa
cadeia de protótipos, o que você vê aqui, ele iria olhar ainda mais para cima na cadeia de heranças.
Podemos testar isso. Pule para o registro do console. Agora, homer.cool. Lembre-se, .cool não está disponível em nosso construtor
original. Em seguida, vai olhar para baixo a cadeia de protótipos, atualizar. Obtemos o valor de true. O mesmo vale para métodos também. Também podemos adicionar
métodos diferentes ao protótipo. Em vez de ter esse método disponível em nosso construtor, o que vou fazer é copiar isso e comentar isso. Cole isso fora do nosso usuário. Desta vez, em vez de acessar
o objeto por meio disso, vamos acessar
nosso user.prototype , assim como fizemos antes. Desta vez, o nome completo será igual à nossa função. Vamos testar isso
em nosso log do console. O nome desta vez era FullName. Com esse sendo o
método, também precisamos
acessar isso com os colchetes. Isso agora deve
retornar nosso FirstName, adicioná-lo ao nosso LastName. Bom. Se você também
quiser verificar isso está no protótipo ao lado do cool. Podemos remover FullName. Faça login no console,
o valor de Homer. Abra isso,
entre no protótipo, e nossas duas novas edições
estão dentro daqui. Para começar, o protótipo
pode parecer complexo, mas é apenas uma maneira de herdar propriedades e métodos
de um objeto pai, mesmo de um pai que
foi criado como nosso usuário ou do objeto de nível superior
que o JavaScript fornece. Para recapitular, o protótipo é
uma propriedade em um objeto. Ele será disponibilizado para ser
herdado por outros objetos. Um exemplo disso
foi nosso FullName e nossas adições legais. Ambos foram
adicionados ao nosso protótipo, o que significa que agora eles
foram disponibilizados para outros objetos herdarem, como nosso usuário
Homer na parte inferior.
17. Herdando propriedades de objetos: Falamos um pouco
até agora sobre como temos esse principal objeto
JavaScript pai, que tem um protótipo, e como se criaria
novos que
herdam automaticamente certas coisas
através da cadeia de protótipos. Mas e se
quiséssemos também permitir que nossos próprios objetos
fossem herdados também? Em um arquivo inicial, temos
um exemplo
de usuário semelhante do vídeo anterior. Temos um objeto de usuário e podemos começar a perceber
que esse objeto de usuário tem algumas limitações
para nosso uso específico. Aqui estamos criando pessoas
reais como eu e também logo abaixo de
um personagem fictício. Mas se pensarmos nisso, pessoas
reais e fictícias podem
precisar de propriedades diferentes. Podemos, por exemplo,
adicionar o nome do show do qual
o
caractere fictício era. Mas isso não se
aplicaria a uma pessoa real. Isso agora dificulta a expansão desse objeto muito mais. O que podemos fazer, porém, é usar
esse objeto de usuário como base, incluindo apenas as propriedades
mínimas nuas que se aplicam tanto ao usuário real
quanto ao usuário fictício. Em seguida, criamos mais dois objetos, que ambos
herdarão desse usuário original. Ainda temos acesso
a todas as coisas como os nomes e
as ocupações. Mas então também terá propriedades
específicas que
precisamos para cada caso de uso. Para fazer isso, temos um método de
objeto chamado create. Pouco antes de adicionarmos isso
ao nosso exemplo atual, vamos dar uma olhada em
como podemos fazer isso com um objeto autônomo regular. Primeiro, vamos adicionar qualquer
objeto comum na parte inferior. Remova nosso log do console por enquanto, crie um novo objeto
chamado product1. Abra as chaves e
adicionaremos nossas propriedades. O título, novamente,
é bastante genérico, então uma incrível camisa azul. Também a descrição. Simplesmente camisa azul. Como um objeto autônomo é
um objeto genérico que pode ser aplicado a
várias camisas azuis. O título e também
a descrição
serão adequados para
outras camisas azuis. Também podemos alterar
alguns detalhes, como a marca ou o tamanho
de outros produtos. Poderíamos então usar esse método
object.create que
mencionamos antes para criar um segundo produto com base nisso, instalar isso dentro
de uma variável chamada product2 e definir isso
igual a object.create. Dentro do object.create, passamos nosso produto1, o que significa que ele criará
um novo produto chamado product2 com base em nosso produto
original1. Vamos registrar isso neste console, produt2, e ver o que
acontece dentro daqui. Atualizar. Vamos apenas atualizar
esse link dentro do navegador. Inicialmente, vemos
um objeto vazio. Não temos propriedades ou métodos associados a isso. Mas se seguirmos em frente e abrirmos o protótipo anexado, teremos acesso ao nosso título e também à nossa descrição que é herdada do nosso produto1. É assim que o método
create funciona. Ele cria um novo objeto e usa o objeto existente que
passamos como protótipo. Novamente, observe como também
temos um segundo protótipo também. Temos o nosso próprio primeiro, que é a descrição
e depois o título. Então, mais adiante na
cadeia, temos todas
as propriedades e métodos
que vimos anteriormente, que são herdados
do topo
da cadeia do objeto. Como já aprendemos, mesmo que nosso próprio
objeto esteja vazio, ainda
podemos acessar essas propriedades herdadas
do produto1 pelo nome deles. product2, lembre-se que isso está completamente vazio como
acabamos de ver no console. Podemos acessar os
valores herdados, como título. Também podemos adicionar nossas
próprias propriedades e métodos também, como
seria de esperar. Logo abaixo do nosso produtoT2, podemos acessar isso
pelo nome e, em seguida, definir novas propriedades, como
o tamanho, como pequeno. Registre isso no console, que atualiza nosso objeto. Agora podemos remover todo
esse exemplo e
podemos usar esse conhecimento
que acabamos de aprender. Agora podemos tentar aplicar o
mesmo exemplo ao nosso usuário. Mas a principal diferença
aqui é que temos uma função de construtor em
vez de um objeto real. Se fôssemos fazer
o mesmo de antes, vamos criar uma
variável chamada copy, que é definida como object.create. Então, se tentarmos fazer
uma cópia do nosso usuário, vamos ver o que acontece
dentro do console. Salve e atualize. A cópia é uma cópia
da função, que não é o que queremos. O que estamos procurando
é uma maneira de criar funções
mais construtivas que herdem
as
propriedades desse usuário. Vamos começar com o personagem. Logo abaixo do nosso usuário, crie nosso novo construtor de objetos
chamado personagem. Lembre-se de que o objetivo
dessa função é herdar todas as propriedades base
de nossos objetos de usuário. Também vamos adicionar algumas propriedades adicionais que se aplicam
apenas ao nosso personagem. Essa informação extra
que vamos passar é o show de onde
o personagem é. Então, assim como acima,
acessaremos this.show, definindo isso igual
ao valor que é passado para este construtor. Agora, o que fazemos é criar
um novo objeto de caractere com a propriedade show e também herdar todas essas
propriedades também. Mas isso, precisamos entrar em
nosso personagem e primeiro acessar nossa função de
construtor de usuário, na
qual podemos acessar
uma função de chamada. Esse método de chamada está disponível no protótipo de uma função e permite uma função
pertencente a um objeto chamado dentro
de um objeto diferente. Ou seja, agora podemos chamar uma função de usuário de dentro da
nossa função de personagem. Esse método de chamada não é
exclusivo para esse caso de uso. Ele pode ser usado sempre que
eu quiser acessar uma função ou um método localizado
em um objeto diferente. Essa função do usuário também usa
esses quatro parâmetros. Podemos copiá-los e também
adicionar isso ao nosso personagem. Agora, lembre-se que Homer
é um personagem,
então, em vez de basear
isso no novo usuário, vamos
basear isso no novo personagem. Como o quarto
argumento que vou mostrar, logo após Springfield,
podemos passar nosso último valor, que são os Simpsons. Esses cinco valores agora correspondem
aos valores de cinco caracteres passados para o nosso construtor.
Vamos experimentar isso. Podemos remover nossa
cópia de antes
e, em vez disso, registraremos
o valor de Homer. Isso agora mostra que Homer
é um objeto de personagem. Ele tem a propriedade show com
o valor dos Simpsons. Sabemos que homer.show agora também
deve funcionar. Mas e as outras propriedades
herdadas? Podíamos ver antes do objeto
Homer que ele
só teria acesso à
propriedade show no nível superior. Não tínhamos mais
nada, como o FirstName e o LastName, a ocupação ou vidas. Bem, vamos experimentar isso
e ver o que acontece. Primeiro, experimente a ocupação. Atualize e
recuperamos o valor de indefinido. Vamos tentar mais um. homer.lives e isso também
é indefinido também. As propriedades herdadas
não parecem funcionar aqui. Isso ocorre porque estamos
perdendo alguns detalhes ao chamar nossa função de usuário
dentro do nosso personagem. Primeiro de tudo,
precisamos copiar todos
esses parâmetros que são
passados e também adicionar isso
ao nosso método de chamada. Mas, além disso, também
precisamos passar
essa palavra-chave. Mencionamos anteriormente
que essa palavra-chave pode ser uma coisa complexa de
se entender. Teremos mais sobre isso mais tarde. Mas isso está basicamente
dizendo que ao executar nossa função, podemos acessar os
valores usando isso. Assim como estávamos acima. Rolando para baixo, ainda estamos
tentando registrar homer.lives. Vamos atualizar isso e
agora obtemos o valor
de Springfield. Podemos tentar mais um,
o primeiroNome. Tudo isso está funcionando corretamente. Assim como uma recapitulação, porque isso
pode ser bastante confuso, estamos criando um
novo objeto Homer baseado em nosso personagem. Esta função de
construtor de caracteres
tem apenas uma propriedade própria, que é o show ao qual
o caractere pertence. Mas também está herdando todas
as propriedades e métodos
de nossos objetos de usuário, que estamos passando
aqui. Na verdade, também não precisamos
adicionar esses programas, pois ele pertence a essa função
específica. Com toda essa complexidade, se quisermos verificar qual de nossos construtores criou
um objeto específico, como Homer, podemos usar
algo chamado instanceof. Podemos verificar isso
dentro do log do console. Podemos verificar se o objeto homer é uma
instância do caractere. Deve ser o valor
verdadeiro, já que somos base do nosso novo personagem. Mas se
passássemos nosso usuário, este será falso. É assim que o JavaScript
faz as coisas. Ele tem objetos desde o início dos quais
podemos herdá-lo. Como recém-chegado,
nem sabemos que isso está acontecendo nos
bastidores. Mas se fôssemos cavar um
pouco mais fundo assim, podemos começar a
entender que
isso é para que cada novo objeto, objetos também se referindo
a outros tipos, como matrizes e funções,
e têm um conjunto de propriedades
e métodos úteis que podemos usar cada vez que
criamos nossos próprios objetos. Como acabamos de discutir, também
podemos aproveitar
essa herança de protótipo por
nossos próprios objetos, se necessário.
18. Copiar propriedades de objetos: Nos vídeos anteriores, nos
aprofundamos em objetos com coisas como construtores de
objetos, cópia
e protótipos. Mas às vezes,
simplesmente queremos copiar as propriedades de um
objeto para outro. Existem algumas maneiras
diferentes de fazer isso. Primeiro de tudo, temos
o personagem base com informações que podem ser aplicadas a todos os novos
personagens Simpsons que criamos. Informações bastante genéricas
e, abaixo, também
temos um objeto homer com algumas propriedades que
se aplicam apenas a esse caractere. Para homer e também quaisquer outros
caracteres que
criamos, também precisamos mesclar em todas
as propriedades do caractere
base também. Uma maneira simples de fazer
isso é apenas referenciar esse caractere base dentro
do objeto homer. Nós adicionamos isso como uma propriedade, o temos no caractere base e testamos isso
no console. Já temos um
registro de console para o valor do homer. Se abrirmos isso, temos as quatro propriedades originais e também veremos nosso caractere
base. Isso funciona completamente bem, mas cria um objeto de caractere
base qual precisamos abrir
e mergulhar. Nosso caractere base é aninhado um nível mais profundo do que todas as
nossas outras propriedades. Mas seria melhor
se pudéssemos pegar todas
essas
propriedades de caractere base e colocá-las
efetivamente ao lado do
que já temos. Uma maneira de fazer isso é
usando objetos espalhados, que olhamos anteriormente, que eram os três pontos. Passando os três pontos antes do
nosso objeto de caractere base. Agora, não vemos o objeto de caractere
base qual precisamos mergulhar. Em vez disso, vemos todas as propriedades
do caractere base
ao lado de nossos homer. Também poderíamos usar essa
técnica para espalhar tantos
objetos diferentes quanto quiséssemos. Por exemplo, se tivéssemos um personagem homer Simpson com superpoderes para um episódio
em particular, poderíamos fazer algo assim. Poderíamos criar um novo
objeto chamado SuperHomer. SuperHomer
também precisaria herdar o caractere base e também todas as
informações existentes do homer. Também podemos remover isso também. Podemos usar spreads pass
em ambos os objetos. O caractere base e também as informações do
homer existente. Além disso, também
podemos passar nossas próprias propriedades, o que é específico para
esse único objeto. Por exemplo, poderíamos definir
poderes como iguais a verdadeiros, e isso agora deve exibir um objeto grande
dentro do navegador. Vamos mudar o log do nosso
console para ser SuperHomer. Atualize e agora temos nove propriedades
diferentes
neste objeto. Temos a queda
do personagem base, a vanguarda do objeto Homer, e também os poderes definidos como verdadeiro. Poderíamos remover ou
comentar esse objeto, e agora vamos dar uma
olhada em outra maneira
de copiar as propriedades do objeto
para um novo objeto. Isso é feito com um
método de objeto chamado assign. Acesse nosso objeto principal,
o método de atribuição. Isso vai levar
duas coisas. Primeiro, o objeto de destino para
o qual você deseja copiar. Vamos copiá-lo para
nosso objeto homer, e o segundo é o
objeto que você deseja copiar. Usando nosso
exemplo original para mover todas as propriedades do nosso caractere
base para o homer. Passe isso como
o segundo valor. No log do console para ser homer. Pule para o console. Isso agora
mescla todas as propriedades do caractere
base em
nosso objeto homer. Funciona efetivamente como o operador de spread que
procuramos antes. Além disso, se precisássemos, podemos
armazenar esse novo objeto em uma variável como MergedHomer. Isso também deve funcionar
exatamente da mesma forma. Essa técnica atribuída e
também as anteriores, são realmente úteis e
algo que você pode usar com frequência em JavaScript. Ele tem muitos casos de uso, como se tivéssemos um usuário e um pedido, podemos querer anexar
um objeto de usuário ao nosso pedido antes de salvar no banco de dados,
para que saibamos quem realmente
fez o pedido. Você também provavelmente encontrará muitos casos de uso próprios também.
19. Objetos de Estilo CSS: Na seção DOM, criamos
nossos próprios elementos HTML. Em seguida, analisamos como adicionar estilo
CSS a esses
elementos usando JavaScript. No arquivo do Estilo, temos um exemplo disso
na parte inferior, uma seção de cabeçalho simples com
um título sem hambúrgueres de carne. Então, abaixo disso, dentro
do nosso script,
temos várias
propriedades de estilo aplicadas. Isso funciona bem como podemos
ver dentro do navegador, mas pode ser uma maneira bastante
longa de fazer as coisas. Também não é reutilizável em
outros elementos. Uma solução para isso é
criar um objeto de
estilo contendo todas as propriedades
e valores CSS que precisamos. Vamos até o fundo
e comentaremos todos esses
estilos existentes e vamos recriá-los dentro
de um objeto de estilo. Armazene isso dentro de uma
variável chamada estilos. Diga isso igual a um objeto, e nós
os replicaremos efetivamente dentro daqui. Primeiro de tudo, a tela é
igual ao valor de flex. Como este é um objeto, precisamos
separá-lo com uma vírgula e o próximo é JustifyContent. Como isso é JavaScript, também
precisamos fazer
esse caso de camelo, JustifyContent e
cada palavra após a primeira precisa começar
com uma letra maiúscula. O valor, isso pode ser o mesmo, isso pode ser espaço entre eles. Em seguida, temos um valor de preenchimento. Novamente como uma string,
zero superior e inferior e 10 pixels
à esquerda e à direita. Plano de fundo. O
que temos aqui? Temos um valor RGB. Vamos copiar isso.
Finalmente, a cor. Vamos pegar o valor
que já temos , colar isso. Vamos até o
navegador e atualizaremos. Não temos nenhum
estilo aplicado. Agora precisamos de uma maneira de realmente
aplicar o objeto de estilo ao
nosso elemento de cabeçalho. Assim como no último vídeo,
podemos usar object.assign. Isso copiará todas as nossas propriedades de objeto
de
estilo para esse elemento de cabeçalho. Na parte inferior do
script object.assign. Queremos
aplicá-los ao cabeçalho. As propriedades do objeto
que você deseja aplicar são nossos estilos. Mas, assim como é assim, não
funciona se
atualizarmos o navegador. A razão pela qual é exatamente
como fizemos originalmente, em vez de aplicá-los
ao elemento de cabeçalho, precisamos aplicá-los
ao header.style, então at.style e
atualize e agora tudo deve entrar em
vigor no navegador. No momento, você pode estar um
pouco confuso sobre o motivo pelo qual um método de objeto como atribuir está funcionando em um
elemento como o cabeçalho. Bem, isso ocorre porque
nossos elementos, como muitas coisas em JavaScript também
são classificados como objetos. Podemos ver isso
com um registro de console. Podemos usar o operador typeof
e o valor do cabeçalho. Então vamos ver o que acontece
dentro do console. Atualize e você pode
ver que o cabeçalho, mesmo que este seja um elemento, é um tipo de objeto. Quando criamos novos
elementos, estamos
criando objetos de elemento e é
assim
que podemos ter acesso a propriedades, métodos e eventos. Já usamos
propriedades
como acessar os atributos, lista de
classes e
HTML interno para citar alguns. Os métodos que usamos incluem queryselector
e addEventListener. Todos eles estão disponíveis
neste objeto de elemento. Mas por que criar um objeto de estilo
em vez de CSS normal? Bem, o CSS provavelmente é
fácil para muitos casos de uso, mas dessa forma também tem
seus próprios usos. O principal deles para mim
é o fato de ser controlado com JavaScript. Podemos alterar
valores dinamicamente. Se tivéssemos um jogo, por exemplo, poderíamos mudar o
plano de fundo para ficar vermelho se o jogo acabasse. Podemos fazer um flush de contagem regressiva mais rápido à medida que está se
aproximando do fim e muitos outros casos de uso excelentes
atualizando qualquer um desses
valores dinamicamente.
20. Usando loops em objetos: objetos podem ter
muitos valores como
sabemos e, assim como nos arrays, loop é uma maneira conveniente repetir algo
para cada propriedade. Há algumas maneiras
diferentes que podemos usar para fazer loop sobre objetos
e, primeiro, damos uma
olhada no loop for-in. Dentro do arquivo desta lição, temos uma
função de construtor no topo, que já vimos antes
para criar um novo usuário. Observe que as
adições do protótipo são
comentadas e
veremos o porquê em breve. loop for-in deve
parecer bastante familiar. Já analisamos isso
no loop na seção, mas quero mostrar
algo mais relacionado a ele. Como atualização, é assim que
ele fica dentro do nosso código. Começa com a palavra-chave for
e, para este exemplo,
vamos fazer um loop sobre nosso objeto homer. Precisamos criar uma
variável para cada uma das propriedades
dentro daqui, então o primeiro nome,
o sobrenome, a ocupação e vidas. Isso dentro de uma variável ou uma constante chamada propriedade
dentro do nosso objeto homer. Agora vamos abrir
os aparelhos encaracolados e, em seguida, aqui dentro, podemos fazer o que
quisermos com essa propriedade. Mas agora faremos um log de console, abriremos os ticks traseiros para que possamos inserir nossa variável de propriedade, que é o nome da nossa propriedade, como o primeiro nome ,
adicionar dois pontos e
depois poderíamos também acesse o valor
da propriedade. Novamente, inseriremos
isso como uma variável então precisamos acessar
nosso objeto homer completo
e, dentro dos colchetes, passaremos a propriedade da qual
queremos pegar o valor. Salve isso,
atualize e vemos cada uma
dessas quatro propriedades dentro do console. Vemos os
nomes de propriedade reais, como o primeiro nome, e então usamos isso para selecionar o valor da propriedade do objeto
homer, como homer. Em seguida, podemos usar esses valores para construir elementos para
agora adicioná-los ao DOM. Primeiro, é necessária uma
lista não ordenada, que podemos usar como um invólucro
para todos esses valores, então salte para a nossa
seção de corpo fora do script, tenha uma lista não ordenada e o primeiro passo é pegar uma referência aos nossos elementos. Const ul é igual a
Document.querySelector, passe em nossa lista não ordenada. Isso agora nos dá duas coisas. Temos um loop, então
estamos fazendo um loop sobre todas as propriedades
dentro do nosso objeto, e agora isso nos dá um
elemento para anexar isso. Com isso sendo uma lista
não ordenada, precisamos criar
um novo item de lista para cada um desses valores. Const li para o nosso item de lista, criaremos isso com
Document.createElement (). Um elemento está em li. Lembre-se, ao criar
novos elementos, esse geralmente é um processo de
três estágios. Criamos os elementos, criamos o conteúdo, como o nó de texto, e depois
os mesclamos juntos. A segunda parte disso é para o texto que vai dentro
do nosso elemento de lista. Fazemos isso com
document.createTextNode (), replicamos o que
vimos dentro do console. Tudo o que precisamos fazer é copiar o conteúdo de
dentro daqui e colar isso dentro
do nosso método. Remova o log do console,
mescle-os
acessando primeiro nossos elementos e use o método
chamado appendChild. Vamos passar nosso texto. Isso criou um novo elemento
autônomo ou um item de lista autônomo
e, em seguida, para cada
loop, precisamos mesclar isso ou inseri-lo em
nossa lista não ordenada. Assim como fizemos
acima, pegaremos nossa lista não ordenada e
usaremos o AppendChild. Passando o item da lista que acabamos criar. Salve e atualize. Lá vamos nós e essa é
uma boa maneira de
estruturar nossos objetos para serem
exibidos dentro do navegador. Mas de volta a esse protótipo, que você mencionou antes, que atualmente é
comentado. Se descomentarmos isso, vamos salvar isso e agora,
novamente, atualize o navegador. Agora também vemos esses dois valores
de protótipo dentro daqui. Isso é algo que precisamos
observar e se
não quisermos fazer um loop
sobre esses protótipos, que geralmente é o caso, podemos eliminá-los usando um método de objeto chamado
hasOwnProperty (), que podemos usar
dentro do loop. Vamos até o
nosso loop for-in
e, no topo,
adicione uma instrução if. Passaremos em
Homer.hasOwnProperty (), passando nossa variável de
propriedade. O que estamos fazendo aqui
é que estamos acessando nosso objeto homer completo e , em seguida, verificando cada
propriedade um a um. Estamos verificando se a propriedade
específica pertence a esse objeto homer ou se ela é herdada
por meio do protótipo. Se isso for verdade, queremos
executar nosso código abaixo. Caso contrário, será um valor de protótipo e
, portanto, ignorado. Agora podemos cortar isso fora do lugar e adicionar isso dentro
de nossas declarações if. Atualize, e essa é uma maneira de
ignorar nossos valores de
protótipo herdados. Outra maneira de fazer loop
sobre objetos é primeiro convertê-los em matrizes. O objeto tem alguns métodos disponíveis que você
pode usar para fazer isso
e, dependendo se você deseja acessar a propriedade do objeto, o valor
de ambos como um par. Vamos começar com um
método primeiro chamado entradas na parte inferior, colocar em um log de console
para objects.entries () e nosso valor de objeto de homer. Teste isso, pule
para o console e ele ainda
retorna na matriz. Isso não só
retorna na matriz, cada uma das propriedades também
é uma matriz. Ele contém o nome da propriedade e também o valor
como você pode ver aqui. Esse método não inclui os valores do protótipo como
faz com for in. Se estivéssemos usando
isso, poderíamos ignorar as declarações if que
temos aqui. Para tentar isso, e
manter o mesmo exemplo,
aumente o for no exemplo, e depois comentar isso. Cole isso logo abaixo. Devo mencionar, não
precisamos dessa declaração if,
pois não precisamos
eliminar nenhum dos protótipos
herdados. Remova o invólucro, deixando
essas quatro linhas dentro. Desta vez, em vez de fazer
um loop sobre nosso objeto homer, agora
vamos fazer
uso de object.entries. Vamos mover isso,
e assim como fizemos dentro do log do console
substituindo objetos, entradas de
dados com
o valor de homer. Salve e atualize.
Dentro do navegador, vemos os valores de indefinido. Isso pode não ser óbvio
no início do porquê disso, mas isso ocorre por causa do
tipo de loop que estamos usando. Atualmente, usamos
um loop for in, que é usado em objetos. Mas agora estamos convertendo
homer para ser um array. Isso agora significa que precisamos fazer uma pequena alteração e,
em vez disso, usar um loop for, então mude para ser de, e lembre-se agora desta propriedade, em vez de retornar uma única
propriedade como era antes, agora vai apontar
para uma matriz que contém dois valores como
nosso primeiro nome e homer. O que podemos fazer em vez
disso é a estrutura D
usando a matriz, que nos dará a
chave e também o valor. A chave neste caso é
igual ao primeiro nome, e o valor
será igual a homer para cada um de nossos itens. Passe isso. Primeiro de tudo, a chave
e, em seguida, também passa nosso valor. Salve isso. Recarregar. Isso novamente
funciona conforme o esperado. Essa é uma
boa maneira de fazer loop, o que não envolve
o protótipo. Se quisermos,
também podemos acessar as chaves, todos os valores individualmente
também. A maneira de fazer isso. Como exemplo em
nosso log do console, se quisermos apenas
acessar as chaves como nome
e sobrenome, podemos usar um
método de objeto chamado chaves, onde passamos
nosso objeto homer, e há nossas quatro
chaves sem os valores. Por outro lado,
se quiséssemos apenas
acessar os valores
e não as chaves, podemos usar object.values, e isso retornará isso de
volta dentro do console. Isso também é comumente usado em declarações if assim. Poderíamos dizer se object.keys (), passar nosso objeto e acessar a propriedade length
é maior que zero. Podemos então fazer algo
dentro daqui. Isso verifica se um objeto não está vazio antes de executar algum código e depende apenas se você deseja acessar a chave, o valor ou ambos.
21. Objetos Dinâmicos: Este vídeo será convertido criando objetos mais dinâmicos. isso, quero dizer tanto a chave quanto o valor podem
ser alterados usando JavaScript. Quando criamos novos objetos, assim como fizemos com
esse objeto doméstico, estamos usando um
valor primitivo simples, como strings, mas nossos programas nem
sempre serão tão rígidos. Também podemos precisar inserir
dados que podem mudar, como uma variável. Além disso, mesmo com os nomes
principais, como FirstName e LastName
e ocupação. Isso tudo pode ser dinâmico também. Agora vou mostrar
algumas maneiras de fazer isso. Primeiro, as formas mais
tradicionais
e, em seguida, uma forma que foi
introduzida na ES2015. Começamos inserindo
variáveis como valores, e isso é bem simples de fazer. Vamos primeiro criar uma variável chamada FirstName e definir
isso igual a homer. Podemos então referenciar
essa variável dentro do valor da nossa propriedade quando
criamos nosso novo usuário homer. Lembre-se, como
agora estamos nos referindo a uma variável em vez de uma string, precisamos remover as aspas
ao redor. Salve isso e atualize. Isso funciona como antes, mas desta vez agora estamos
apontando para uma variável. Já sabemos que podemos adicionar novas
propriedades também como essa. Podemos acessar nosso objeto, acessar a propriedade likes e definir isso igual a uma string. Salve e
atualize, e isso também é
adicionado ao nosso objeto. Atualmente, o valor das curtidas
é definido como uma string. Também podemos querer que isso
seja dinâmico também. Vamos tentar definir isso como uma variável em vez de uma string. Remova as cotações. Vou criar
isso como uma variável logo acima, const curtidas e inserir nossa string dentro dos ticks traseiros para que possamos inserir nossa variável
passando nosso FirstName. Nesse caso,
dirá homerlikes, seguidos por um valor específico. Eu envio FirstName,
um texto de curtidas, e agora nossos gostos dentro
daqui apontarão para nossa variável, que agora é mostrada
no navegador. Ele também leva em consideração
nossa variável FirstName também e a coloca como
parte da string. Se
tivéssemos várias curtidas, também podemos querer numerá-las. Podemos começar criando
um valor inicial. Vamos dizer que o número seja igual
a um valor inicial de um. Em seguida, adicione esse
valor numérico à nossa variável. Como esperaríamos,
temos apenas o único número 1. Se duplicássemos isso e alterássemos isso para ser um segundo
valor, como Donuts, poderíamos incrementar esse número em um
usando plus plus. Isso será aumentado para
cada um de nossos valores. Lembre-se de que tudo isso
é construído usando nossa
função de construtor de objetos na parte superior. Também podemos fazer tudo isso usando a abordagem literal do objeto. Na parte inferior, vamos
criar um literal de objeto, e vamos chamá-lo de homer2, e definir isso igual a um objeto
literal onde
definimos nossas propriedades,
como FirstName, ou também podemos fazer uso de nosso
Variável FirstName também. Registre isso no console. Como você pode ver, nossa
variável também pode ser inserida usando
essa abordagem também. Mas isso pode começar
a parecer um pouco confuso porque aqui, apontamos para todas as variáveis
firstName, mas também o nome da propriedade
ainda está apontando para essa variável
firstName também. Então, por que vemos essa saída como uma string em vez
do valor de homer? Bem, para a chave, não precisamos envolver esse nome entre aspas. Isso sempre será
exibido como uma string. Então, como iríamos
tornar essa propriedade chamada dinâmica se não pudéssemos usar uma
variável assim? Bem, uma opção seria
apenas criar um objeto vazio sem
nenhuma propriedade interna. Em seguida, poderíamos adicionar
propriedades como
fazemos acima usando os
colchetes ou, alternativamente, usando
um recurso ES2015 chamado nomes de propriedade computados. Poderíamos usar os colchetes diretamente dentro de nossos objetos. Então cerque nossa
propriedade firstName com os colchetes, que agora diz que
o código dentro
desses colchetes não
deve ser tratado como uma string. Em vez disso, ela é avaliada como
uma expressão JavaScript, ou
seja, se agora exibirmos
isso dentro do navegador, em vez disso, agora vemos
o valor de homer, que é nossa variável. Mesmo esse controle total
sobre a chave de propriedades e também o
valor das propriedades usando JavaScript. Também poderíamos extrair
nossas propriedades assim como fizemos de cima. Poderíamos acessar isso
sem o prefixo homer , colar isso em. A única diferença é,
em vez dos iguais, precisamos mudar
isso via dois pontos. Também podemos adicionar nosso
segundo a Donuts. Adicione uma vírgula, coloque dois pontos. Vamos tentar isso no
navegador. Abra isso. Então isso agora está
inserido, mas em vez dos valores de um e dois, vemos os valores de
dois e três já que já
incrementamos
isso logo acima, podemos comentar este. Está nos levando de volta ao
nosso exemplo original. É assim que podemos usar nomes de propriedades
computados com nossos objetos para tornar
a chave e também o valor mais dinâmicos
usando JavaScript.
22. Tipos primitivos e de referência: Usamos
muito variáveis em codificação e JavaScript para armazenar nossos dados. Mas se formos um pouco mais fundo, há alguns
conceitos importantes para entender e esses são os valores que
armazenamos caem em dois grupos. Para entender melhor isso, quero primeiro atualizar o que
já sabemos sobre tipos de dados. Temos valores primitivos, que são valores simples, como uma string ou um número
que não tem métodos. Também temos tipos de objetos também. Esses dois grupos
se relacionam diretamente com o que
vamos ver agora e isso está armazenando tipos
primitivos e de referência. Uma variável de string
seria primitiva, e um tipo de objeto, como uma variável de matriz seria classificado como
um tipo de referência. Ambos os tipos
afetam o comportamento dos valores quando os transmitimos
e os comparamos. Vamos primeiro entrar em
nosso projeto inicial e dar uma olhada nas primitivas. No script para o arquivo
desta lição, criaremos uma nova
variável chamada Dog e definiremos isso
igual a uma string. Em seguida, crie uma segunda
variável chamada NewDog, e definiremos isso igual à
nossa variável dog original. Esta é efetivamente uma
cópia da nossa primeira variável. Então vamos reatribuir o
NewDog para ser outra coisa. Lembre-se, a maneira de
fazer isso é selecionar o nome da nossa variável e defini-lo igual
a qualquer novo valor. A próxima coisa a fazer é fazer um teste rápido com um registro de console, começando com nossa
primeira variável de cachorro
e, em seguida, um segundo
registro de console para o nosso novo cão. Vamos ver. Bem, isso
congelou dentro do console. Vemos o valor do poodle, que você esperaria do
nosso primeiro log do console, e o segundo
log do console do NewDog. Mesmo que esta tenha sido originalmente atribuída à variável de poodle, esta foi atualizada para
ser o texto do Labrador. Nada de inesperado
aqui, mesmo tendo copiado uma
variável originalmente, a nova ainda é
um valor separado, completamente independente
do original. Basicamente, podemos modificar
o cão original, ou o novo cão e eles não se
afetarão. Esse é o comportamento
das primitivas. A variável aponta para
o valor salvo real. armazenamento de tipos de objetos
se comporta de forma diferente. Vamos fazer um exemplo
usando um objeto que podemos copiar exatamente
como fizemos aqui. Primeiro de tudo,
criaremos nossa variável chamada laptop 1 e definiremos
isso igual a um objeto, que é claro que é
um tipo de objeto. As propriedades ou marcas e os dados dentro
dela não importam. O modelo definiu qualquer
valor como uma string
e, logo abaixo, faremos uma cópia disso,
assim como fizemos
com nosso NewDog. Este será
chamado de laptop 2, que é igual ao laptop 1. Da mesma forma que fizemos no topo com nossas primitivas, atualizaremos ou reatribuiremos nosso laptop 2 e
adicionaremos uma nova propriedade, como o tamanho. Desta vez, para os registros do console, o primeiro é o laptop 1. Também verei qual
é
o valor do laptop 2 . Teste isso. Atualizar. Veremos que esses dois
valores são
exatamente os mesmos. Isso pode parecer muito
estranho porque temos a propriedade size no laptop 1 e também no laptop 2, mesmo que
tenhamos adicionado isso apenas
à nossa segunda variável. O que significa que
parece ser um link entre o laptop um e o laptop 2. Quando criamos nossas
variáveis armazenadas em uma primitiva logo acima
com uma string, a variável aponta para o valor exclusivo real
armazenado na memória, e esses são todos valores exclusivos. No entanto, quando
criamos uma variável contendo um tipo de objeto, o objeto ainda é
armazenado na memória. Mas essas variáveis,
como o laptop 2, possuem uma referência à localização
desse objeto em vez do valor real, daí o tipo de referência de nome. Aqui estamos criando nosso laptop
original, e cada vez que criamos
uma cópia como o laptop 2, tudo aponta para o
mesmo objeto original. Como todas as cópias estão
apontando para o mesmo valor, é por isso que ao
modificar qualquer uma delas, como aqui, o original também
será atualizado. Algumas outras linguagens
nos permitem mudar esse comportamento. Mas com o JavaScript é corrigido. Assim como uma rápida recapitulação e talvez esclareça se você não tem certeza. Quando criamos uma
variável para armazenar em uma primitiva, como uma string, a variável aponta para um valor
único real armazenado na memória, o que significa que nosso Cão e
também nosso NewDog, são completamente valores únicos
e independentes. No entanto, quando
criamos um novo tipo de objeto com base em um objeto original, a versão copiada
manterá uma referência à localização do objeto original na memória, daí o tipo de referência de nome. Isso é algo que
você provavelmente não se importa muito com
isso até que talvez tenhamos um problema
em que você muda
um objeto e todos eles
mudam um problema
em que você muda inesperadamente, e você não sabe o que
está causando o problema. Com isso em mente, a seguir, abordaremos como podemos
comparar dois objetos.
23. Comparando Objetos: O que aprendemos
no vídeo anterior é que um valor primitivo é único e armazenado por um valor e um tipo de objeto é
armazenado como referência. Isso agora nos ajudará a
entender melhor o comportamento que estamos prestes a ver ao
comparar dois objetos, é que dentro de nossos arquivos
iniciais temos dois objetos semelhantes com
as mesmas propriedades. Ambos têm a
marca e também o modelo e também
os mesmos valores também. Vamos usá-los para
comparar a qualidade. De um palpite sensato, você pensaria que se
comparássemos ambos, eles serão
considerados uma verdadeira correspondência. Isso seria uma suposição justa,
já que ambos têm a mesma marca e
também o modelo também. Saltando para o console, se fizermos uma comparação
com primitivas, isso é bem simples. Se 1 for igual a 1, isso retornará
o valor de true. Isso é simples porque
as primitivas têm seu próprio valor exclusivo
armazenado na memória. comparação de valores funciona
como você pode esperar. Objetos são
pouco menos óbvios. Como você pode esperar, comparar o mesmo objeto como
esse resulta em verdadeiro. Laptop 1, se compararmos
isso com ele mesmo, que é laptop 1,
isso também é verdade. Mas se mudarmos o laptop 1
para ser igual ao laptop 2, mesmo que ambos tenham
a mesma marca e modelo, obteremos um valor de false. Mesmo que esses
dois objetos tenham exatamente
o mesmo conteúdo, eles não são considerados iguais. O motivo é porque
esses são tipos de referência. Lembre-se, uma
variável de tipo de referência aponta para um
local na memória, não para o valor real. Aqui,
na verdade, não estamos comparando o conteúdo
desses dois objetos. Em vez disso, estamos comparando dois locais de memória
diferentes. É por isso que a
comparação é falsa. Sei que isso pode parecer
um pouco confuso, mas é assim que
o JavaScript funciona. Voltando ao que vimos
no vídeo anterior, o que você acha que acontecerá
se copiarmos um objeto? Por exemplo, se
definirmos a constante com laptop 3 e definirmos isso
igual a laptop 1. Bem, vamos testar isso. Podemos verificar se o laptop número
1 é igual ao laptop 3. Lembre-se, aqui estamos fazendo uma cópia e isso resulta
em um valor verdadeiro. Agora, este
volta verdade porque quando criamos o laptop 3, não
copiamos o
conteúdo do laptop 1. Em vez disso, o laptop 3 agora
apontará para a localização original do laptop 1 na memória. Independentemente de como todas essas variáveis são
armazenadas nos bastidores, talvez ainda
precisemos de
uma maneira de comparar as propriedades de dois objetos. Precisamos de uma maneira de comparar o
laptop 1 com o laptop 2, o
que
resultará em verdade. Uma maneira de fazer isso é usar um método JSON chamado stringify. Analisaremos mais dados JSON. Stringify é uma maneira de
converter um objeto em uma string e
ele se parece com isso. Analisando o JSON, um método
chamado stringify, vamos analisar
o valor do laptop 1. Se testarmos isso
dentro do console, podemos ver que nosso objeto está
sendo convertido em uma string. Comparando uma
versão de string do laptop 2 com uma
versão de string do laptop 2 tornará nossa comparação muito mais fácil. Faremos o mesmo. Vamos verificar se isso é
igual a json.stringify. Desta vez, analisaremos
o valor do laptop 2. Pule para o console. Isso é igual a
verdadeiro, já que ambos os valores de cadeia de caracteres são
exatamente os mesmos. Um dos problemas
com o uso desse método é que as propriedades devem estar exatamente
na mesma ordem
para que isso funcione. Se o laptop 1 e a marca
forem nossa segunda propriedade, isso resultaria em falso. Para corrigir isso, temos algumas
maneiras diferentes de verificar isso. O primeiro, que
é muito bom para comparar objetos
simples como este é que poderíamos criar uma
função chamada check igualdade, que
verificará manualmente nossos dois objetos. Quando chamamos isso, estamos
analisando o objeto 1 e o objeto 2. Em seguida, retornaremos
o valor de if objeto 1. A marca é igual ao objeto 2. Essa é a nossa primeira comparação. Depois, também queremos
verificar se o modelo também
é o mesmo. A dupla e comercial, verifique se object1.model é
igual a object2.model. Este é um longo caminho. É uma maneira manual de fazer
as coisas, mas funcionaria. Podemos verificar isso
chamando nossa função de
igualdade de verificação. Nossos dois objetos serão laptop 1 e também laptop 2, esses são os dois que
você deseja comparar. Para ver qual é o valor de retorno, podemos analisar isso em
nosso log do console, atualizar. Objeto 1 não definido, eu só precisaria ter
certeza de que eles têm um j, atualização, e esse é
o valor de true. Agora, não importa
qual maneira
nossas propriedades estão em
cada um dos objetos. Ainda podemos fazer uma comparação simples
ou manual de cada uma delas. Outra opção é fazer uso de métodos de objeto para acessar
as chaves e os valores. Já analisamos isso
no loop com vídeo de objeto. Lembre-se de que acessamos
o objeto, um O. maiúsculo Podemos subir as
chaves como modelo e marca ou laptop 1, assim. Há
modelo e marca. Além disso, podemos fazer o mesmo
para object.values também. Usando essa abordagem,
podemos modificar nossa função de igualdade de verificação para todas as chaves e valores
e verificar se temos uma correspondência. Desta forma também significa que a ordem das
propriedades não é importante, como foi com
o primeiro método stringify. Como você pode ver, os tipos de objetos
podem ser uma coisa complexa. Se você não entende como
eles funcionam em JavaScript, basta um pouco de
experiência para se acostumar. Mas eu não espero que você se lembre de tudo isso pela primeira vez. Mas apenas estar ciente de coisas como essa realmente o
ajudará
no futuro se você encontrar
algum problema relacionado a objetos.
24. Introdução da seção: Chegando,
teremos um ótimo projeto para você trabalhar
e isso lhe dará
muita prática com o que aprendemos até agora. Este será o nosso projeto chamado Speedy Chef. A ideia é que vamos cozinhar pizzas que vêm
através de pedidos e tentar obter o
máximo de conclusão possível, então com o chef e
podemos começar o jogo, que vai iniciar o
serviço para o cozinha e então podemos ver nossos pedidos
chegando à direita. Quando queremos começar a
trabalhar em um pedido, simplesmente
clicamos em um e seguida, o
puxa para a seção de trabalho, que nos diz quais
pizzas precisamos fazer. Para este exemplo,
precisamos de um presunto e abacaxi e dois pepperonis. Atualmente, começaremos com
o presunto e o abacaxi. Percorra
os passos do método aqui e o primeiro é rolar
a massa. Clique sobre isso. Em seguida, precisamos adicionar nosso molho, pimenta, queijo, adicionar
12 pedaços de presunto. Finalmente, 12 pedaços de abacaxi e
tudo isso é atualizado em nossa
seção aqui. Uma vez terminado,
podemos adicionar isso
ao forno e
se você cometer um erro, também
podemos adicionar isso ao desperdício. Clique nisso e, em seguida, nos
bastidores, ele também faz uma verificação
para garantir que temos todos os ingredientes corretos
que precisamos para nossa pizza. Há presunto e abacaxi, que entram no forno. Podemos passar para o pepperoni, e depois que
terminarmos isso, podemos concluir nosso pedido
e passar para o próximo. Também precisamos nos manter por dentro das coisas porque esses pedidos
continuarão chegando
à medida que o tempo avança. Este é um projeto razoavelmente grande comparado ao que
construímos até agora. Mas a maioria dos quais você já
saberá. É apenas um caso de
construir um pequeno recurso cada vez e você
ficará perfeitamente bem. Ao longo do caminho, eu
lhe darei uma série de tarefas para
experimentar as coisas sozinho, mas não se preocupe, você não
está sozinho. Também vou percorrer
cada etapa também para que
possamos comparar e lembrar, como sempre, há várias
maneiras de abordar as coisas. Se ambos tivermos soluções
diferentes que
funcionam, tudo bem. Dentro dos arquivos iniciais, temos um iniciante básico
com nossa página de índice, que adiciona todo o
layout inicial que precisamos. Também temos algum estilo em nossas folhas de estilo e
isso significa que
podemos pular diretamente em nosso
JavaScript e nos concentrar nisso. Mesmo que pareça o
mesmo que o projeto final, nada realmente
funciona ainda e
estaremos codificando tudo
isso durante a aula. Como iniciante, também
incluí o pizza.svg e também um arquivo JavaScript que está vinculado em
nossa página de índice, que contém três matrizes. Esses três raios nos salvarão
muita digitação. Primeiro é uma
variedade de pizza e dentro aqui, temos vários
objetos de pizza com o nome da pizza, um método para fazer
esta pizza e também as etapas necessárias que
usamos no projeto para verificar se o chef tem fez
a pizza correta e também colocou os ingredientes
na ordem correta. Então, logo abaixo disso, alguns exemplos de pedidos para
começar o jogo e também vamos
gerá-los dinamicamente também. Finalmente, uma lista de ingredientes que precisamos dentro da cozinha. Ótimo, então isso está
tudo pronto para ir. Abra esta
pasta do projeto dentro do navegador e, em seguida, vá a próxima lição, onde
começaremos a trabalhar na listagem desses pedidos
dentro do navegador.
25. Pedidos de Listagem: Este vídeo terá apenas
um objetivo principal e isso é
percorrer todos os pedidos e exibi-los no navegador. Lembre-se de que, logo acima, fornecido com essa pasta, é o array mais antigo que
vamos
percorrer e exibir
dentro do navegador. O local para isso estará no lado direito, na seção lateral. Na página de índice, temos duas seções principais. Temos esse invólucro principal e isso contém
todo o conteúdo, que tem o fundo branco. Depois, à parte com
a ideia de ordens. Por enquanto, isso só tem
um cabeçalho de nível 3. Mas o que vamos fazer
é percorrer todos esses pedidos e
colocá-los nesta seção. Para fazer isso, criaremos uma função chamada
CreateOrdersList. Esta função vai
percorrer a matriz de ordens acima. Para cada um desses
itens na matriz, construiremos uma div, que se parece com
esta seção aqui. Algumas partes disso
serão dinâmicas. Por exemplo,
teremos o número do pedido. Isso vai ser dinâmico
junto com o nome
da pizza e também a
quantidade para cada linha também. Você não precisa se
preocupar com esses comentários. Estes são apenas um guia visual para nos dar uma ideia do que
vamos fazer. Começaremos na parte inferior
criando nossa função. A função é chamada
CreateOrdersList , a palavra-chave function. A próxima coisa é fazer um loop sobre
cada uma dessas ordens. Sabemos como fazer
isso. Podemos usar um loop como forEach. Pegue nossa matriz de pedidos forEach. Lembre-se de que forEach
executará uma função para cada
item em nossa matriz. lugares funcionam logo dentro. Daremos a cada um desses
itens o valor do pedido. Agora, precisamos
basicamente construir nossos elementos como fizemos acima para cada uma
dessas ordens. Começaremos criando
este invólucro principal, que é a div. Adicionaremos uma classe
chamada wrapper de pedidos. Vamos trabalhar
em nosso conteúdo dentro. Sabemos como
criar elementos. Usamos Document.createElements. Como no nome da tag dos elementos, que é uma div dentro de uma variável ou constante
chamada orderwrapper. Em seguida, adicione o nome da nossa classe
selecionando o
nome da variável OrderWrapper. A propriedade chamada className. Assim como vemos acima, este será Order_Wrapper. Então, vamos apenas adicionar um comentário. Este é o invólucro principal. Depois disso,
adicionaremos um comentário. Isso será
adicionar o número do pedido. Esta é a nossa primeira seção
dentro do nosso invólucro de pedidos. Este será um nível
4 nosso título. Armazene isso dentro de uma constante. Lembro-me que ao criar
elementos como esses, precisamos criar
o elemento real e, em seguida, o conteúdo interno. Então, precisamos de duas variáveis. O primeiro é o OrderNumber L, que são elementos de prateleira. Então document.createElements. Precisamos de um nível para dirigir. Em seguida, o texto que
vai entrar, e este é o número do pedido. O nome constante do número do pedido e
criamos isso com
Document.createTextNode. Como isso vai
ser dinâmico, porque cada pedido tem um número
diferente, que vamos pegar
desse ID exclusivo. Vamos colocar isso dentro
dos backticks para
tornar isso dinâmico. Primeiro, o texto da ordem, que é essa parte aqui, seguido de um valor dinâmico. O valor dinâmico
pode ser inserido usando o símbolo do dólar
e as chaves. Primeiro, selecionamos nosso pedido
individual, que é armazenado
nessa variável
e, em seguida, a propriedade de ID. Como sempre, ao criar um
elemento, assim, temos duas
informações independentes e precisamos
mesclar essas duas. Fazemos isso
acessando o pai, que é o
OrderNumbeReleasment.appendChild, onde passaremos
nosso conteúdo real, que é o número do pedido. Isso agora nos deixa com nossa
div, que é o invólucro. Então nosso primeiro elemento, que é o nosso cabeçalho de nível 4, mas ainda precisamos adicionar
esse título ao nosso invólucro. Pegue o Order_Wrapper e , em seguida, usaremos novamente ApendChild, que levará em nosso elemento número de
pedido. Então, temos a primeira
seção aqui
e, em seguida, a próxima parte é
criar nossa própria lista de pedidos. Um comentário rápido, então sabemos
o que estamos fazendo aqui de uma ótima pizza UL para cada pedido, e o invólucro tão
documento.CreateElements. Os elementos eram
uma lista não ordenada. Coloca em uma constante
chamada Lista de Pizza. Isso agora nos dá
uma lista não ordenada, que é o principal
invólucro para todas as pizzas. Mas lembre-se, podemos
ter vários itens de lista porque cada pedido pode
ter mais de uma pizza. Então, como nossos pedidos têm várias pizzas
dentro de uma matriz, precisamos novamente fazer um
loop como para cada um. Para fazer isso, novamente
entramos em nossa ordem individual. Selecionaremos a matriz,
que é chamada de pizzas. Use o loop for each
para executar uma função para cada item ou cada pizza
dentro da matriz, armazene isso dentro de uma
variável chamada Pizza. Em seguida, podemos trabalhar com construção de cada
um desses itens. Cada um desses itens
será um item de lista. Mas primeiro, precisamos
criar esse conteúdo dentro. Temos a quantidade
como uma, e depois um traço, depois um elemento de extensão seguido
pelo nome de cada uma
dessas pizzas. Entre em nossa função e para cada um
desses itens,
criaremos um elemento de extensão para envolver nosso título e armazená-lo
dentro de uma constante. Esta é a quantidade da ordem L, então document.CreateElements. Os elementos serão a extensão e, em seguida, ao lado da
quantidade de cada um
desses itens,
Document.createTextNode. Esta seção
precisa ser dinâmica ou colocada nos backticks. Insira uma variável. acessar a quantidade
primeiro selecionando nossa pizza. Em cada uma dessas pizzas, se dermos uma olhada na matriz, tem uma propriedade chamada quantidade. Também usaremos o
nome da propriedade em breve. Para este, isso
é pizza.quantity, seguido por um traço
logo depois. Pensando nisso, pode
ser um pouco mais fácil se
apenas adicionarmos essa quantidade
em nossa extensão. Em vez de
tê-los um fora, talvez
coloquemos isso
dentro de um elemento, em vez de tê-lo
lá fora por conta própria. Faremos isso acessando
os
elementos de quantidade do pedido.appendChild que está
na variável de quantidade, seguido pelo nosso PizzanName. Para o nosso PizzaName, isso
precisa ser embrulhado também em um elemento de extensão e
, em seguida, o conteúdo interno. Precisamos fazer exatamente
o mesmo que logo acima, criaremos uma constante chamada Pizzanamel
document.createelement. Element é um intervalo seguido
pelo PizzaName, que precisamos criar
com o nó de criação de texto, pegue nossa pizza individual. Então, assim como vimos antes, temos a quantidade seguida
pela propriedade name. Podemos acessar isso
com pizza.name. Mescle esses dois juntos.
Pizzanamel.appendChild não estava no conteúdo do texto,
que é PizzanAme. Ótimo, então temos dois vãos
separados aqui. Temos nossa primeira extensão, que está envolvendo nosso número
individual ou a quantidade de pizzas. Em seguida, um segundo período que
contém nosso PizzaName. Ambos os itens precisam
ser mesclados em um item de lista. Em seguida, o item da lista
precisa ser adicionado ao nosso pai. Então, vamos começar a trabalhar.
Como um novo comentário apenas para manter isso claro. Este é criar um item de lista. Mostre a quantidade e o PizzaName. Primeiros elementos armazenados em uma
constante chamada PizzaItem, Document.createElement.
Este era um item da lista. Temos nosso item de
lista ao redor e, em seguida, precisamos mesclar nossos dois
elementos acima. A quantidade que
é essa variável, e também o PizzaName. Vamos pegar nosso PizzItem. Como estamos anexando
vários elementos filhos, podemos simplesmente usar o append e
esse agora é o nosso primeiro, que era o elemento de
quantidade da ordem. Em seguida, o PizzanameElement.
Estamos quase acabando agora, temos nosso item de lista será criado sem duas partes de conteúdo dentro e agora precisamos adicioná-los à nossa lista
não ordenada. Sua lista sob encomenda é armazenada
na constante chamada PIZzalist. Adicione isso logo abaixo de sua lista.AppendChild não estava
em nosso item de pizza. Estamos quase lá. Agora temos nossos itens de lista adicionados
à nossa lista não solicitada. Mas agora a lista não ordenada também precisa ser adicionada
ao nosso invólucro. O invólucro é apenas essa variável de empacotamento de
pedidos aqui. Mas precisamos adicionar
isso fora do nosso loop. Certifique-se de localizar
o final do nosso loop. O que eu fiz logo abaixo
desta linha aqui. Selecione o
OrderWrapper.appendChild, passando nossa lista de pizza. Esta é agora a nossa
ordem completa rapidamente restrita. A próxima etapa, ou a etapa
final para isso, é agora adicionar isso
à nossa página da web. Precisamos
das seções desses dois. Esta seção é a parte. Podemos pegar isso com
a ideia de ordens. Logo abaixo do nosso invólucro de pedidos, use Document.QuerySelector
para pegar nossos pedidos.AppendChild não
estava em nosso invólucro de pedidos. Vamos tentar isso, agora
precisamos chamar essa função
para que ela funcione. Vamos pegar uma lista de três pedidos, ligar-nos na parte inferior,
atualizar o navegador. A boa notícia é que podemos realmente ver os pedidos na tela, mas não
parece exatamente como esperamos. Vamos dar uma olhada
dentro do nosso código e ver o que precisamos mudar. No momento, estamos
perdendo a quantidade antes do PizzaName real, que é esse
item de lista aqui. Estamos adicionando o número do pedido. Acho que isso só
precisa ser a quantidade do pedido. Isso parece muito
melhor agora temos o número do pedido
no topo, cada um deles
está em sequência, seguido pelo nome
e pela quantidade de cada uma das
pizzas no pedido. Como você pode ver, esta é uma
função bastante longa e, idealmente, queremos refatorar
isso em peças menores e
mais focadas e é
isso que faremos a seguir.
26. Listagem Encomendas Refactor: À medida que escrevemos nosso código e
especialmente à medida que nosso projeto cresce. Queremos refatorar regularmente
nosso código sempre que possível. No momento, nosso código
funciona completamente bem. É nisso que queremos nos concentrar no início, mas também é importante olhar
as coisas regularmente e ver se
podemos melhorar as coisas. Este vídeo vai
envolver-nos refatorando essa única
função que você tem. Divida-o em
menores quando possível. É uma boa ideia ter
funções menores que se concentram em tarefas
únicas e isso ajuda na legibilidade
e na depuração. A maneira como você se
aproxima é, depende você e, muitas vezes, preferência
pessoal. Mas quanto mais perto conseguirmos obter uma função para fazê-lo em uma
única tarefa, melhor. O primeiro passo que vamos
dar é remover todo
o processo de criação de pedidos dessa função e
colocá-lo em uma função autônoma. Retiraremos todo
o conteúdo
usado para criar nosso pedido,
deixando nossa função
“CreateOrdersList” com uma tarefa simples. Essa tarefa é fazer um loop sobre todos os conjuntos de pedidos e
adicioná-los à seção à parte. Para fazer isso, crie uma nova
função logo acima. Este será chamado
para “CreateSingleOrder”. Como essa função
será repetida para cada ordem
dentro da matriz, também
tomaremos a ordem como uma variável movendo-se para baixo e
pular em nossa função. Começando com “OrderWrapper”
dentro do loop, solte todo o
conteúdo
daqui, até onde adicionamos isso ao nosso “OrderWrapper”. Corte isso e devemos
ficar com nosso loop. Em seguida, a seção em
que adicionamos isso ao lado. Agora isso é recortado. Entre em nosso “CreateSingleOrder”
e cole isso em. Agora, se entrarmos em nosso loop onde acabamos de cortar esse código. Agora podemos chamar
isso de “
função autônoma ” que foi chamada de
“CreateSingleOrder”. “CreateSingleOrder”
também precisa aceitar a ordem, já que estamos
passando aqui, que é então usado no
resto da nossa função. Agora, se você pensar sobre isso, isso é simplesmente não
chamar nenhuma função. Na verdade, não está fazendo
nada com ele. Tudo o que precisamos fazer é
retornar a ordem
desta função acima, armazená-la dentro de uma variável e, em seguida,
podemos adicionar isso ao DOM. Primeiro, pegaremos
nosso OrderWrapper, que é a seção completa do pedido, e devolveremos isso
de volta da nossa função. Esse valor de retorno pode
então ser armazenado dentro de uma variável chamada
“SingleOrder”. SingleOrder agora pode ser
adicionado à nossa barra lateral. Vamos experimentar isso,
“Salvar” e “Atualizar”, e tudo ainda
funciona como antes, mas essa função ainda
é bastante longa. Também podemos reduzir
o tamanho desses dois. Mais uma vez, como você
quebra isso se resume à preferência pessoal. Mas o que vou
fazer é terceirizar a criação
do “PIZZalist” para uma nova função e isso também pode ser usado
no futuro também. A seção PIZzalist
é esse loop. Também precisamos pegar
a lista de um pedido, qual armazenamos isso dentro, então copie isso e também o loop. Em seguida, crie nossa função e logo acima chamada
“CreateListOfPizzas”. Só queria tomar
as pizzas. Em seguida, “Cole” em nossa nova seção. Apenas certifique-se de que a
seção correta esteja colada dentro, que é a nossa lista não ordenada, seguida de nossos quatro loop cada. Em apenas um momento em que podemos
realmente chamar essa função. Lembre-se de que isso vai
absorver todas as nossas pizzas para que não
precisemos desta seção de pedidos. Podemos chamar nossas pizzas
diretamente e é variável. Agora podemos chamar
essa função
a partir do local onde
acabamos de cortar esse código.O nome da função
era “CreateListOfPizzas”. Isso precisa ser passado todas as
pizzas para este pedido, que podemos primeiro pegar do nosso pedido e cada pedido
tem a propriedade de pizzas. Assim como fizemos abaixo,
precisamos armazenar isso dentro de uma variável e também retornar algo
para nossa função. O que precisamos voltar no final é o
nosso “PIZZalist”. O valor retornado pode então ser armazenado dentro de uma constante. Se chamarmos isso
constante de “PIZZalist”. Ele também se relaciona bem com nosso nome de variável
que usamos antes, que é então adicionado ao
nosso “OrderWrapper”. Dê a isso um “Salvar”
e experimente isso, “Atualizar” e todos os pedidos
ainda funcionam conforme o esperado. Funções de refatoração
como essa nem
sempre são para você e você pode
decidir até onde deseja ir. Nada está mudando em termos da forma como o projeto funciona. Ainda vemos apenas as ordens
na tela, mas agora
temos três funções claras
com uma tarefa específica. Temos no topo,
“CreateListOfPizzas”, que é
retornado dessa função. Essa lista de pizzas é então adicionada ao
DOM quando criamos nossa única ordem e uma
“SingleOrder” é então loop em nossa última função e depois adicionada ao DOM.
27. Função do auxiliar do elemento: Outro refator que
podemos fazer para nos
salvar muito código é
olhar para o que estamos repetindo atualmente em nossas
funções e ver se existe uma maneira de terceirizar isso em uma função
reutilizável. Se dermos uma olhada em nosso
código neste estágio inicial, e iremos até a função
CreateListOfPizzas. Já temos
algumas coisas que estamos repetindo atualmente. Estamos repetindo a
criação desses elementos em nossas três etapas. Faz parte da quantidade. Estamos criando um elemento span. Estamos criando o TextNode
e, em seguida, estamos mesclando
esses dois juntos. Estamos fazendo o mesmo
pelo nosso PizzaName. Estamos criando um elemento. Estamos criando um TextNode
para o conteúdo, mesclando-os juntos,
descendo um pouco mais para
CreateSingleOrder. Também estamos fazendo
algo semelhante aqui, estamos criando nosso elemento de texto, que está em um invólucro de nível 4. Estamos criando o
conteúdo e, em seguida estamos anexando estes juntos, e isso está tudo bem. Isso é algo
que precisamos
fazer para criar nossos elementos. Para cada vez que criamos um novo elemento em qualquer
uma dessas funções, é um processo de três partes que
tomou três linhas de código. Seria bom
criar uma função
auxiliar para reduzir a quantidade de código, e essa será
a tarefa desse vídeo. Criaremos uma
função auxiliar que assumirá
o nome do elemento. Esta é a seção criar
elementos. Você vai pegar o conteúdo, que é o TextNode, irá mesclá-los, que normalmente é
nossa terceira linha, e então retornaremos
esse novo elemento para o que chama nossa função. Vamos começar a trabalhar.
Crie uma nova função que ajudará
com isso chamado BuildElement. BuildElement também
precisa aceitar duas coisas. Ele precisa pegar o nome
dos elementos como o h4 e também o
conteúdo que entra. Passará isso quando
chamarmos essa função, e a primeira será o ElementName e a
segunda for ElementContent. Dentro da função
será bastante familiar pelo
que já fizemos
e, de fato, podemos copiar
qualquer um desses exemplos. Resolvendo CreateSingleOrder. Tenha todas as três linhas de código em
que
criamos o elemento, criamos o conteúdo e as mesclamos. Se você quiser, podemos copiar todas as três
linhas, colá-las dentro. Então precisamos tornar isso
um pouco mais genérico. Começando com a
primeira constante. Isso é para o elemento. O segundo é
para o conteúdo
e, em seguida, dentro
de ambos os colchetes, podemos passar os dados que
são passados para todas as funções. O primeiro é para
o ElementName e o segundo podemos
remover o que
temos atualmente , colocar em ElementContent. Altere os nomes das variáveis. Este será
Element.appendChild, passando o conteúdo
para esse elemento. A última coisa que precisamos fazer, atualmente
estamos
criando um elemento. Também precisamos devolver isso de
volta da nossa função, ele pode ser acessado
dentro do nosso código. Retornará os elementos completos
depois de serem mesclados, e essa função
agora pode substituir qualquer uma
dessas três linhas de código
que cria um elemento. Se pegarmos o nome da nossa função e também os colchetes
com o conteúdo, agora
podemos substituir qualquer uma
dessas seções logo acima. Começaremos com
CreateSingleOrder, para todos os
elementos do número do pedido, o número da ordem
e, em seguida, a terceira linha que mescla ambos
juntos. Vou substituir isso pela
nossa função ElementName. Este é um h4. Para o conteúdo,
podemos substituir isso pelo mesmo conteúdo
que usamos logo acima. Pegue isso e cole isso dentro. Mantenha nossa nomeação consistente,
pois estamos
usando atualmente uma constante
chamada OrderNumberel, e acessamos
isso logo abaixo, também precisamos armazenar
isso dentro de uma constante com o mesmo nome. o que acontece aqui é que estamos construindo nossos elementos
dentro de nossa nova função. Em seguida, retornamos isso de
volta da função, que é então armazenada
dentro dessa constante, que podemos usar
no resto do nosso
código, logo abaixo. Se você quiser, podemos remover as linhas de código existentes
e, em seguida, podemos passar para a nossa primeira função que
é CreateListOfPizzas. Temos todas as três
linhas aqui. Vou comentar isso para que
possamos usá-lo como referência. Precisamos passar em nossa função
BuildElement, passando nossos dois valores. O primeiro valor é o nosso span. O segundo
copiará nosso modelo literal. Agora isso em. Também para isso
na parte inferior, usamos no nome
constante
original do elemento OrderQuantity. Podemos copiar isso e
armazená-lo dentro do valor de retorno. Remova essas três
linhas, se você quiser. Em seguida, o PizzaName. Essas três linhas para fora. Criaremos nossa
constante, que é o mesmo nome de PizzanAmeel. A função Order também
é tomada em um elemento span, e o conteúdo é pizza.name. Remova esses.
Ambos são os mesmos, só
precisamos mudar acabou. Este deve ser
o PizzanAmeel. Vamos trazer este aqui. Bom. Agora vamos salvar isso e mais no
navegador e podemos testar. Tudo ainda está
funcionando bem. Saltando para o
console, não
vemos nenhum erro dentro daqui. Nossa barra lateral tem nossos
pedidos gerados à direita. Temos os números do pedido,
temos os nomes das pizzas e também as quantidades também. Isso tudo parece agora
ainda funcionar bem, e espero que você possa ver os benefícios de fazer
coisas assim. Mesmo que nossa função tenha
tomado algumas linhas de código, cada novo elemento que criamos reduzirá três linhas
de código em uma. Também podemos usar isso muitas
vezes no futuro durante nosso projeto para
economizar ainda mais código. Não se trata apenas de
legibilidade e organização. Uma única linha como essa significa menos chances de erros de digitação e também um aumento na
velocidade à medida que nosso programa cresce.
28. Selecionando A Ordem Atual: Temos alguns pedidos
à direita nos levem a frente
e, em breve, criaremos
novos aleatoriamente também. Pouco antes de avançarmos para isso, quero mostrar
como as coisas vão
funcionar para que você possa imaginar o que vamos fazer. Assim que o jogo começar, nossos pedidos começarão a
entrar e aparecer à direita. O chef, que é o jogador, então,
clicará em uma
ordem para começar a trabalhar, que então moverá esse pedido para a seção trabalhando. Esta seção é o que
vamos nos concentrar agora. Mais tarde, iremos
ainda mais longe clicando em uma pizza específica
na seção trabalhando em. Em seguida, isso exibirá o
método e também o definirá como o atualmente trabalhando em
pizza dentro da cozinha. Agora podemos nos
concentrar em clicar em um pedido e movê-lo para
a seção trabalhando em. Como você deve ter adivinhado, para
fazer isso, vamos criar uma nova função logo acima da
nossa lista de pedidos de criação. É uma nova função chamada
SelectCurrentOrder. Para chamar essa função,
precisamos ouvir um clique em qualquer um
desses pedidos. Para fazer isso, precisamos avançar para nossa
função CreateSingleOrder. Se dermos uma olhada
nesta seção, precisamos adicionar um ouvinte de
eventos a cada um desses pedidos. Podemos clicar
nisso e, em seguida, mover essa ordem específica
para a seção correta. Logo abaixo de onde
adicionamos essa classe. Pegue o invólucro de pedidos, que é a div em torno de
cada uma dessas ordens. Adicione um ouvinte de eventos. Isso ouvirá agora um
clique que acionará nossa nova função chamada
SelectCurrentOrder, nos
dá o teste fazendo um log de console dentro
de nossa nova função. Passe as
informações do evento para que possamos obter os elementos corretos
que estão sendo clicados. Em seguida, registramos isso com e.target. Vamos verificar
isso no console. Agora, o que precisamos fazer é clicar
em qualquer um de nossos pedidos. Você vê a margherita.
Vemos o presunto e o abacaxi. Isso não é
exatamente o que queremos. Podemos clicar em qualquer um
dos números do pedido, qualquer no conteúdo. Mas o que queremos fazer é
tornar toda a seção de pedidos ativa, então é apenas uma
única área clicável. Entenda melhor
isso, vamos pular para a guia Elementos
e dar uma olhada. Agora vamos entrar na seção de
lado que contém nossos pedidos e
clicaremos em qualquer um
desses divs com a
classe de wrapper de pedidos. O que queremos é
apenas poder clicar nesta div
com a classe de wrapper de pedidos e ignorar todos
os cliques que estão
nos elementos aninhados. Uma maneira de fazer isso é
ouvir agora um clique
em qualquer um desses elementos
aninhados, como os itens da lista ou
o cabeçalho Nível quatro. Em seguida, suba a árvore de
elementos até encontrar a primeira div com
a classe de invólucro de ordem. Para fazer isso, podemos
ouvir exatamente qual elemento
foi clicado, como a lista não ordenada. Em seguida, podemos continuar
subindo a cadeia para verificar se o elemento pai é
esse invólucro de pedidos. Há algumas
maneiras diferentes de fazer isso. Poderíamos armazenar uma referência qual elemento filho
foi clicado, como nossa lista não ordenada. Em seguida, podemos continuar verificando
dentro desse loop se o elemento pai for
esse wrapper de ordem. Ou uma maneira fácil é usar um método de elemento
chamado mais próximo. O método mais próximo tomará um elemento como
o que clicamos. Em seguida, ele continuará subindo em direção à
raiz do documento através de
todos os nós pais até atingir
uma correspondência de seletor. O seletor pode ser uma classe, um ID, um nome de elemento. Assim como podemos fazer
com o seletor de consultas. Vamos dar uma
olhada em como fazer isso dentro da nossa função. Primeiro, vamos começar
uma referência aos nossos elementos que é
clicado, que foi e.target. Em seguida, encontraremos os elementos pai
mais próximos com essa classe
de wrapper de pedidos. Podemos fazer isso acessando o elemento que é clicado,
chamando o método chamado mais próximo. Bem, estamos passando a consulta
que estamos procurando. No nosso caso, queremos
procurar o order_wrapper. Com isso sendo uma classe,
adicionamos o ponto como um prefixo. Isso dentro de uma constante
chamada OrderWrapper. Em seguida, podemos verificar isso
registrando isso no console. Agora, se atualizarmos e tentarmos clicar em
qualquer um desses pedidos. Verifique se a
guia Console está selecionada. Se tentarmos
clicar em qualquer coisa do lado de fora, não
vemos nada
no console que é esperado pelo título da pizza. Isso retorna para
o invólucro de pedidos dos pais. Podemos abrir isso e
verificar se é o Pedido 1. Vamos tentar um diferente. Esta é a Ordem 3
e também a Ordem 2. Bom, agora, independentemente de qual parte da ordem em
que clicamos, ele sempre sobe até o invólucro de pedidos
dos pais, para pegar o
conteúdo completo deste pedido. Usando esse método, se
nenhuma correspondência for encontrada, obteremos de volta
um valor null. Também podemos verificar
isso antes de adicionar nosso pedido na seção
trabalhando em. Logo abaixo de onde
selecionamos nosso invólucro de pedidos, adicione uma declaração if onde
passamos em nosso invólucro de pedidos, podemos verificar se isso não
é igual a nulo. Se
clicarmos com sucesso em um invólucro de pedidos, agora
precisamos pegar
este invólucro de pedidos e movê-lo para nossa seção
trabalhando em. etapa 1 é pegar uma seção
trabalhando e armazená-la dentro de uma
constante chamada OrderDiv. Isso é igual ao documento. QuerySelector e o seletor de
consultas que
precisamos como uma ideia de trabalhar. Em seguida, usando append child, podemos adicionar nosso
invólucro de pedidos. O OrderDiv. AppendChild passando em nosso invólucro de pedidos
que foi clicado. Ótimo, vamos tentar isso
. Podemos fechar o console e tentar qualquer
um desses pedidos. Vamos tentar o Número 3 e isso agora aparece nas
seções, já que
adicionamos isso como elementos
filhos Ordem 2, Ordem 1, e
tudo isso funciona muito bem. No entanto, só
queremos poder trabalhar em um único pedido por vez. Precisamos de uma maneira de
verificar se há apenas um único pedido selecionado
e colocado nesta div. Uma maneira de fazer isso é
primeiro acessar a
seção Working on e podemos verificar quais elementos filhos
estão aninhados dentro. Veja que é melhor
pegarmos uma referência ao nosso div place isso
dentro de um registro de console. Então podemos encadear no fim.children. Pule
para o console. Clique em um de nossos pedidos
para adicionar isso à seção. Se olharmos de perto, a
primeira coisa que temos é uma coleção HTML com
um cabeçalho de Nível 3. Depois disso, temos nossa
div com a classe de embalagem de pedidos, que
acabamos de adicionar. Também podemos confirmar isso se formos à nossa página de índice que está funcionando na seção só tem
um único cabeçalho de Nível 3. Com isso em mente, o número de elementos
filhos agora pode ser
usado para interromper a função. Se o número de
elementos filhos for maior que um seja, temos nosso
cabeçalho de Nível 3 seguido por
qualquer um de nossos pedidos, podemos fazer isso de volta em nossa função de ordem atual
selecionada. Remova o log do console, substitua-o por
uma instrução if. Podemos verificar se as crianças. comprimento é maior que um. Se for, simplesmente
retornaremos alterar essa função. Também podemos remover
as chaves curvas e substituí-la pela nossa declaração de
retorno. Vamos experimentar isso.
Salve e atualize. Eu clico na primeira ordem,
isso funciona bem. Agora não podemos adicionar
mais pedidos. A última coisa
a fazer, queremos
passar sobre a ordem para a seção
trabalhando em é também
remover o ouvinte de eventos. Não precisamos mais que esta
seção seja clicável, para que possamos removê-la
de nosso invólucro de pedidos. Podemos fazer isso antes de adicionar isso à nossa seção div. Ao acessar os elementos
que são armazenados no wrapper de
ordem chamado
RemoveEventListener. O ouvinte
que queremos remover são os eventos de clique seguidos por SelectCurrentOrder que
corresponde ao nosso ouvinte de eventos. Sempre que possível,
ouvintes de eventos como esse devem ser removidos quando
não forem mais necessários. Isso ajuda a manter o desempenho
atualizado, pois o navegador não precisa
mais fazer
uma tarefa desnecessária, mas também para eliminar comportamentos
inesperados. Em seguida, vamos cobrir a
seleção da pizza, qual vamos trabalhar na
qual vamos trabalhar dentro da cozinha.
29. Definir A Pizza Atual: Veja o fluxo do nosso projeto, já
fizemos o
primeiro passo que foi
mover a ordem selecionada
na qual clicamos para a seção Pedido para
a seção Trabalhar em. Em seguida, precisamos
ser capazes de selecionar a pizza para trabalhar
clicando nela. Essa pizza selecionada
deve então mostrar na área
da cozinha e
também exibir o método, todas as etapas para criar isso. Se você der uma olhada aqui,
criei alguns passos que vamos usar para cumprir esse objetivo no topo que é tornar os nomes das pizzas clicáveis e depois movê-los
para a área da cozinha. Se você quiser,
pode acompanhar esses cinco passos
e tentar recriar isso sozinho ou
se preferir, pode
acompanhar comigo. Em primeiro lugar,
para poder clicar nessas pizzas, Passo 1 inclui
adicionar uma classe de nome de pizza a cada
um desses itens. Vamos pular para a função do
CreateListsOfPizza , vamos localizar isso. E então é aqui que
criamos cada uma de nossas pizzas dentro dos elementos
do span. Pouco antes de fazermos qualquer adição, adicionaremos nossa classe
selecionando a variável do elemento
nome da pizza. Selecione a ClassList, o método chamado add,
onde, como uma string,
passaremos o nome de pizza_name. Essa é a Etapa 1,
cuidada. Vamos rolar de volta para baixo. etapa 2 é localizar a função
SelectCurrentOrder. Como podemos ter
várias pizzas, precisamos selecionar todos os elementos
de extensão. E lembre-se, se
tivermos
vários elementos, precisamos usar um
QuerySelectorAll. Podemos pegar todos
esses elementos usando
essa classe de nome de pizza,
que acabamos de adicionar. Então, vamos localizar esta
função SelectCurrentOrder,
então, na parte superior,
usaremos QuerySelectorAll para pegar todos esses elementos de
pizza, armazená-los dentro de uma variável chamada pizzas
Document.QuerySelectorAll. Podemos pegá-los com
o novo nome de classe que acabamos de criar,
que era pizza_name. Lembre-se que o objetivo
é poder clicar em um dos nossos nomes de pizza, como nosso presunto e
abacaxi ou todo o pepperoni. Então, agora podemos clicar gratuitamente
em qualquer um desses nomes. Então pegue nossa variável,
que é pizzas. Podemos usar forEach para executar uma função para cada
um desses itens. Cada uma das
pizzas individuais armazenará em uma variável de pizza
e, em seguida, podemos adicionar um EventListener a cada uma
dessas pizzas, então
pizzas.addEventListener. Evento será um clique, que executará uma
função que ainda não
criamos chamada
setCurrentPizza. Certo? Então, vamos criar
essa função na parte inferior, função
setCurrentPizza. Como acionamos isso
usando um evento de clique, também
podemos passar as informações do
evento para nossa variável e verificar se isso está funcionando
com um log de console. Então, para pegar os elementos reais em
que você clicou, como presunto e
abacaxi ou pepperoni. Para pegar o texto,
podemos fazer isso com e.target em uma propriedade
chamada innerText, verificar se tudo está
funcionando corretamente. Vamos experimentar isso, pular para
o console e atualizar. Então, a primeira coisa
a fazer é
clicar em um de nossos pedidos, oops, ele gerou um erro
no EventListener. Vamos dar uma olhada no que
poderia estar causando isso. Temos uma variável não utilizada, então isso só precisa de um s, porque isso contém
várias pizzas. Vamos experimentar isso
agora. Podemos clicar em nosso pedido. Isso funciona muito bem. Agora, se clicarmos no
texto de presunto e abacaxi, vemos isso no
console, Pepperoni. Bom, isso é
exatamente o que queremos. Agora, se voltarmos
ao nosso setCurrentPizza, obviamente, o objetivo é não registrar isso no console, o que queremos fazer é
salvar o nome da pizza em
uma variável e, em seguida, adicionar isso apenas depois do nosso texto
de Atualmente fazendo. Se saltarmos para a
página de índice e
localizarmos esta seção, podemos ver logo
depois temos um intervalo com o ID
de current_pizza. Então, vamos
armazenar esse texto em uma variável e, em seguida,
colocá-lo nessa extensão. Vamos fazer isso dentro
de nossa função com um registro de console e armazená-lo dentro de uma
constante chamada PizzaName. Pegue nossa área de extensão com
Document.querySelector. Use #, já que isso estava com
o ID de current_pizza. Defina o InnerText para esse elemento igual à
nossa variável acima. Vamos experimentar isso. Não
precisamos mais do console. Mova qualquer um desses pedidos para a seção trabalhando em. Clique em “Pepperoni” e
há nosso texto exibido, “Presunto e abacaxi” e
também o “Margherita”. Em seguida, usaremos esse elemento
selecionado para exibir as etapas necessárias dentro
da seção de método.
30. Métodos de Split & Join: Anteriormente, definimos o nome
atual da pizza dentro da cozinha
quando isso foi clicado. Agora vamos passar para exibir o método
para
fazer essa pizza dentro
da seção de métodos. O método é todas as etapas
necessárias para criar cada pizza. Temos isso na parte superior
do nosso arquivo JavaScript. Dentro da nossa página de índice, podemos entrar em todas as pizzas, e isso tem o nome da pizza
que você já usou, e também o método também. Se tomarmos esse
método Margherita como exemplo, isso
terá três etapas. O primeiro é rolar
a massa, o segundo é
adicionar o molho e o terceiro é
para cima com queijos. Vamos validar que o
chef concluiu as etapas mais tarde usando
as etapas necessárias, mas, por enquanto, tudo
o que queremos fazer é focar em exibir esse método
dentro do navegador. Como você pode ver, esse método é tudo uma única sequência de texto, e o que vamos
fazer neste vídeo é dividir cada uma
dessas etapas para
exibi-las no navegador. Então precisamos do passo 1,
precisamos do passo 2 e também do passo 3 para
exibi-los de forma formatada. Para fazer isso, poderíamos entrar em nossa função de pizza atual, mas para manter as coisas mais limpas
e mais abstratas, vou criar
uma nova função na parte inferior. Pule até o
fundo do nosso projeto. É uma nova função
chamada DisplayMethod. Isso também vai
precisar pegar
o nome da pizza para que saibamos qual método precisamos obter, então passe isso
em nossa função, e precisamos chamar
essa função cada vez que definirmos a pizza atual, ou seja, esta função logo acima
quando clicamos na pizza, e isso é exibido
dentro daqui. Quando isso é
clicado, sabemos em qual pizza precisará trabalhar. Isso faz sentido
chamar nossa função de dentro de lá. Vamos fazer isso. Chamaremos nossa função, que é DisplayMethod, e lembre-se que isso
também precisa receber o nome atual da pizza, que você armazenou
dentro dessa variável. Ao longo da nossa página de índice, atualmente já
tem uma seção chamada método, que
você pode ver aqui. Isso tem o ID do método um nível 3 no topo
e, em seguida, temos duas seções. Temos o
nome da pizza seguido
pelo método que iremos inserir
em breve. Como você pode imaginar,
esta é a seção com
a
qual vamos trabalhar. Podemos começar na primeira seção que
é o nome da pizza. nossa função,
já temos o
nome da pizza para que possamos usar documentos.QuerySelector ('pizza_name') .innerHTML que teria visto o conteúdo do texto interno será igual à nossa
variável, que é PizzaName. Antes de prosseguirmos,
experimente isso no navegador, preciso atualizar e passar um pedido para a seção
trabalhando em. Clique em “Pizza” e podemos ver nome da
nossa pizza aqui dentro. Isso também é atualizado à medida que
clicamos em diferentes. O próximo passo em nossa página de
índice é pegar nosso método de pizza e colocar
um método dentro daqui. Lembre-se, nosso objeto pizza tem essa propriedade de método
que podemos acessar, e para encontrar isso, podemos usar o método Erase find
é encontrar método que podemos usar para filtrar
este particular suportado pelo nome da pizza
que já temos, e então podemos selecionar
o método para cada um. De volta à nossa função bravo full pizzas array
method, que é
encontrado, e encontrar vai
executar uma função para cada valor dentro da
nossa matriz de pizzas, e você pode colocar uma
função irregular se quiser, mas como essa será uma declaração simples, adicionarei isso em sua própria
linha com uma função de seta. Esta função vai
absorver a pizza individual,
depois acessar o nome de cada
pizza individual no loop, e podemos verificar se isso é
igual ao nosso nome da pizza, que é passado
para essa função. O nome atual da
pizza clicado é igual a qualquer um dos nossos
nomes de pizza na matriz, armazenaremos essa
pizza selecionada dentro de uma variável ou constante
chamada SelectedPizza. Em seguida, faremos um registro do console e verificaremos que
tudo está funcionando bem, a constante de SelectedPizza, e vamos atualizar isso
dentro do navegador. Saltando para o console. Primeiro, clique em um “Oder”,
selecione uma das pizzas. Isso é presunto e abacaxi,
e podemos ver que o objeto
completo entre abacaxi foi devolvido. Vamos tentar mais um.
O pepperoni. Ótimo, então tudo isso
funciona e agora podemos filtrar isso para
retornar apenas o método. Tente isso novamente. Os passos que
precisamos dentro de lá, e é diferente para
cada um deles. Ótimo, então isso agora
retorna uma sequência de texto, e precisamos
dividir essa string e exibir cada etapa
como um item de lista. Para isso, o JavaScript tem um método de string
integrado chamado split, que strings herdam
através da cadeia de protótipos. Esse método pegará
nossa única string, que temos agora, dividi-la em um determinado
ponto que especificamos
e, em seguida, retornará uma nova matriz contendo todas
essas substrings. É assim que ele se
parece em nosso código. Este é o nosso método, então
podemos simplesmente remover isso
da cadeia de log do console para
o final, o método de divisão JavaScript, e queremos passar
em qual seção
da string queremos dividir isso além, e então nosso caso, uma parada completa é ideal, e isso ocorre porque se
olharmos para a nossa corda, cada um desses passos que
temos termina em uma parada completa. Isso é perfeito para
quebrar nossa corda, e lembre-se que isso
retornará uma nova matriz, que podemos armazenar
dentro de uma constante. Finalmente, antes de
prosseguirmos, faremos um log de console passando nossa constante,
que é MethodSteps. Vamos experimentar isso.
Selecione um pedido, selecione a pizza e isso agora retorna uma nova matriz com
todas as nossas etapas em vigor. Também podemos fazer o oposto
também se quisermos, e isso é pegar uma matriz
de valores como
temos aqui e convertê-los
em uma única string. Podemos fazer isso com o
método chamado join. Lembre-se, MethodSteps
é uma matriz. Podemos fazer o inverso
passando o método de junção. O Join está em uma única string. Podemos testar isso
clicando em uma Pizza. Faça com que uma única string
volte para e cada valor é
separado por uma vírgula. Se quiséssemos, poderíamos mudar esse separador para ser
qualquer outro personagem, como um traço. Experimente isso. Agora tenha um traço entre
cada um desses valores. Isso é útil se
você precisar unir uma matriz de valores
em uma única string. Sabemos agora que podemos
percorrer matrizes e fazer algo com cada
valor, e no HTML, definimos o nome da pizza atualmente com
esta seção aqui, e o próximo passo é pegar nossa segunda div com
o id de PizzaMethod. Estou colocando nossos valores de matriz. Pegue isso com documents.querySelector ('#pizza_method')
.HTML interno e aqui
vou definir isso como
igual a uma string vazia. Se um método já tiver
sido definido anteriormente, podemos limpá-lo antes de
adicionar nosso novo. Em seguida, listaremos nossas etapas
pegando nossa matriz,
que é MethodSteps. Como você tem vários valores, vamos percorrer cada um
deles com um loop for each, que executa uma função
para cada valor. Podemos resolver cada
um desses valores na variável chamada método. Em seguida, construa nossos elementos. Instale isso dentro de uma
constante chamada elementos. Temos
documentos.CreateElements mais os elementos que
você deseja criar. Vou escolher um elemento p
e, em seguida, o conteúdo do texto, Document.createTextNode e o conteúdo que
você deseja passar é o texto do nosso método. Colocar no
método dentro
mescla elements.appendChild
passando nosso texto. O passo final é pegar novamente nossa seção de método de pizza,
então copiaremos isso, colaremos isso e, em seguida,
podemos adicionar isso usando o AppendChild passando
nossos elementos. Vamos salvar isso e atualizar, selecionar um novo pedido. Pepperoni. Lá vamos nós. Há o nosso título de pizza e também as etapas necessárias para
cada uma das pizzas. Bom. Tudo isso agora está
funcionando e com boa aparência. Há apenas um pequeno
refator que podemos fazer. Lembre-se, criamos um
novo elemento de texto aqui, mas também temos
uma função auxiliar chamada BuildElements, que leva em nosso nome de
elemento, conteúdo e retornos é um valor
recém-construído. Volte para o nosso loop.
Podemos armazenar isso dentro de uma constante chamada etapas. Isso é igual
ao valor
de retorno da nossa função BuildElement. Passando os elementos p. Em seguida, o conteúdo, que
é o método que
vamos mover essas
próximas três linhas e passar em nossos passos. Vamos experimentar isso,
selecione um novo pedido. Tudo isso funciona exatamente da mesma forma, mas salvamos
algumas linhas de código. Este é outro bom passo
concluído para o nosso projeto, e se você é um iniciante, eu sei que isso pode ser
muito acontecendo aqui, mas o importante
a lembrar é que
já cobrimos a maioria
dos o que estamos fazendo aqui. É apenas o caso
de
dividi-lo em tarefas menores, garantindo que cada etapa
funcione ao longo do caminho.
31. Adicionar Pizzas Ao Forno: O estágio final de mover
esta pizza é
movê-la da
área da cozinha até o nosso forno. Ainda não criamos a pizza, mas veremos
como fazer isso em breve juntamente com a verificação de que
usamos os ingredientes corretos. Mas, por enquanto, podemos
usar este PizzaName que temos e mover isso
para a seção do forno. Agora nosso forno será
uma matriz para armazenar
várias pizzas, também
precisaremos de algumas
outras variáveis também. Vamos criar essas duas
funções bem acima, e logo abaixo de nossos ingredientes, criar nosso forno com
a palavra-chave let, que inicialmente
será uma matriz vazia. Depois disso, precisamos definir o número máximo de pizzas
que caberão no nosso forno, que é a capacidade do forno. Vou buscar
um valor de seis. Em seguida, precisamos
acompanhar as pizzas que fizemos para
um determinado pedido. Se você pegar a Ordem 3, por exemplo, diz quatro pizzas, Order 2 tem três
pizzas e precisamos acompanhar quantas
fizemos atualmente. deixe PizzasCompletedFororder, que será inicialmente zero. Agora temos isso, podemos criar nossa primeira função que será usada para empurrar a pizza
para o nosso novo conjunto de forno. Para baixo, crie uma
função chamada AddToOven. Por enquanto, este forno
vai tomar o atual PizzaName. Podemos pegar isso da nossa cozinha se formos
à nossa página de índice. Até a área da cozinha, lembre-se que temos esse espaço
com o ID de current_pizza, e isso armazena nosso nome de pizza. Pegue isso com
Document.querySelector ID, que é current_pizza. Em seguida, o InnerText. Armazene isso dentro de uma
constante chamada PizzaName. Lembre-se de que nem sempre
temos uma pizza selecionada. Atualmente, temos o valor de presunto e abacaxi, mas se
atualizarmos esse elemento geralmente
está vazio. Para verificar isso,
colocaremos em uma declaração if. Podemos verificar se o
PizzaName está presente. Se for, adicionaremos
isso ao forno com
o método de matriz chamado push, passaremos no PizzaName
e, em seguida, um log temporário do console para verificar se tudo está funcionando. Vamos ter o Console,
pular para o navegador. Podemos verificar esse
login apenas um segundo, mas primeiro precisamos realmente
chamar essa função. Vamos chamar essa
função adicionando um ouvinte de cliques ao
botão que já temos, que está dentro da
nossa seção de cozinha e logo abaixo da nossa pizza
atual. Tenha esse botão para AddToOven. Atualmente, ele tem uma classe,
mas podemos adicionar um ID. Selecione este AddToOven e , em seguida, pegue este forno
em nosso script. Documents.querySelector,
o valor de ID de AddToOven, então podemos adicionar um ouvinte de
eventos. ouvinte de eventos ouvirá um clique neste botão, que executará uma função chamada addToOven.
Vamos experimentar isso. Com o Console Aberto, clique em um de nossos
pedidos. Selecione a pizza. Atualmente, estamos com
presunto e abacaxi, e acionamos nosso ouvinte de
cliques com forno e vemos presunto e abacaxi
são empurrados para a matriz. Vamos tentar pepperoni. Clique nisso e, novamente, isso continua adicionando
pizzas ao nosso forno. Ótimo. Agora sabemos que isso funciona, podemos estender isso
um pouco junto com a adição de um
PizzaName ao forno. Atualmente, apenas vemos
dentro da matriz, mas também precisamos listar
isso na seção do forno. Junto com
a listagem do PizzaName, também
podemos definir o horário
que foi colocado no forno. Isso ocorre porque depois
também adicionaremos um tempo de cozimento também. Então, para isso, crie um novo objeto e fazemos isso dentro
de nossas declarações if. Logo acima de onde ele
empurra para o forno, criaremos um objeto
chamado PizzaForoven. A primeira propriedade é a PizzaName que é armazenada
na variável PizzaName, que você já possui e seguida, uma propriedade
chamada TimeAdded. Por enquanto, um simples valor de
espaço reservado está bom, voltaremos a isso mais tarde. O passo final por enquanto é
apenas colocar a constante de pizza para forno em
nosso método push. Pouco antes de testarmos
isso, lembre-se de que adicionamos uma variável chamada
PizzasCompletedFororder. Podemos aumentar isso
pelo valor de 1. Vamos verificar se tudo isso
funciona dentro do Console. Temos uma pizza, adicionamos isso
ao forno e há
nosso novo objeto. A matriz do forno agora está recebendo
as pizzas como podemos ver. Em seguida, uma função para percorrer esse array e
exibi-los na seção do forno. Logo após empurrarmos nossa
nova pizza para o forno, vamos chamar
uma nova função chamada DisplayOvenItems. Chamamos isso cada vez que criamos uma nova pizza e
a adicionamos ao forno, que atualizará
a interface do usuário. Ainda não criamos isso, então vamos adicionar isso logo acima. Para começar dentro
da página de índice, precisamos pegar nossa seção de forno e, se dermos uma pequena
olhada em nosso código, temos o invólucro do forno
que tem o
título de nível 3 e, em seguida, esta
div vazia com o ID do forno, e este é o local
onde adicionamos nossas novas pizzas. Podemos pegar este
documento.QuerySelector, o ID do forno e em seguida, primeiro definiremos
isso para uma corda vazia. Isso limpa nosso forno
antes de atualizá-lo. Enrole nossa matriz de forno e, como isso não é um array,
podemos usar forEach. Executamos uma função forEach
valor dentro de lá, cada valor será uma pizza específica que
vamos embrulhar em uma div. const PizzaDiv é igual a
document.createElement, cria nossa seção div. Vamos adicionar uma classe a
isso para o nosso estilo, então pizzadiv.className
é igual a pizza_div. Lembre-se, dentro de nossos arquivos
iniciais, também
temos uma imagem SVG para nossa pizza. Isso será usado para
exibir dentro
do forno cada vez que adicionarmos
uma nova pizza ao forno. O que podemos fazer é tratar isso como uma imagem ou criar um
novo elemento de imagem. Temos Document.createElement, os elementos de imagem com IMG. Em seguida, podemos definir a propriedade
source como igual ao nosso SVG. Este é chamado pizza.svg, e também está na mesma pasta mas podemos fazer referência a
isso pelo nome. Temos um invólucro
com uma aula, temos uma imagem,
também precisaremos do nome da pizza. Para fazer isso, podemos fazer uso de nossa função chamada
BuildElement para criar essas fotos e armazenar o valor de retorno em uma
constante chamada PizzaName. Nossa função auxiliar,
que é BuildElement, isso pode ser um elemento p e como o PizzaName será uma variável, inseriremos isso
dentro dos ticks traseiros, com todo o símbolo
e depois
calibrar isso e, em seguida, lembre-se, cada um dos nossos
itens de forno é armazenado
nesta variável de pizza para que
possamos acessar pizza ou nome. Estes são todos os
elementos que precisamos. Agora é apenas um caso
de adicioná-los ao nosso invólucro PizzaDiv. Selecionaremos este PizzaDiv. Podemos usar o append para
adicionar vários valores, adicionar alguma nova imagem
no PizzaName. A seção final agora é
adicionar isso ao nosso forno. Assim como acima, usaremos o QuerySelector para pegar nosso forno, AppendChild, colocando
em nosso PizzaDiv. Está um pouco acontecendo lá, mas vamos atualizar e
testar tudo isso está funcionando. Coloque em um novo pedido, selecione a pizza, adicione o
pepperoni ao forno. Há nossa imagem que
criamos aqui, e também nosso nome de pizza
abaixo, presunto e abacaxi. Ótimo, e isso
tudo está funcionando agora. Como mencionado, ainda
precisamos voltar para realmente criar nas pizzas, mas agora sabemos que esse passo
está pronto quando o fazemos.
32. Começando & Terminando O Jogo: Nesta lição, resolvi alguns passos para experimentar
as coisas sozinho. O que pretendemos cobrir
é criar duas funções. Uma função
será usada para iniciar o jogo e outra para finalizá-lo. Essas funções serão
chamadas a partir de nossos botões HTML, que podemos ver em nosso índice. Esta é a seção de controle do jogo onde temos nossos dois botões. A ideia por trás
desses dois botões é limpar a interface
do usuário, mostrar apenas as coisas corretas, como mostrar apenas
o botão final do jogo quando o jogo estiver
realmente em execução. Usamos o botão Iniciar jogo para iniciar as ordens
chegando e assim por diante. Essas funções também
serão úteis mais tarde também quando
adicionarmos ao nosso projeto coisas
como estatísticas e temporizadores. O que precisamos fazer
é primeiro criar nossas duas funções chamadas
StarTofGame e EndofGame. Em seguida, podemos chamá-los adicionando um ouvinte de eventos dos dois
botões que acabamos de ver. Criaremos uma nova variável, que é iniciada pelo jogo, que será um booleano. Este booleano será
verdade quando começarmos o jogo e falso
quando terminarmos o jogo. Faremos uma verificação condicional
dentro do StarTofGame para retornar dessa função se
esta variável iniciada do jogo for verdadeira. Etapa 5, lembre-se de
que todos os pedidos têm essa classe de order_wrapper. Vou limpar
todas essas ordens em nossa função StarTofGame. Como ainda não
iniciamos o jogo e CreateOrdersList é responsável por
criar esses pedidos. Também podemos mover isso dentro da nossa
função StarTofGame para o CSS. Quando o jogo começar,
mostraremos o botão de término e ocultaremos o botão de parada e, em seguida, faremos
o reverso quando o jogo terminar. Não esquecer nosso
botão final do jogo também precisa ser removido ou oculto quando
o jogo for carregado inicialmente. Como sempre, você pode
experimentá-los por conta própria ou acompanhar
se preferir. Na parte inferior,
lembre-se que o primeiro passo é criar nossas funções. A primeira função
foi StarTofGame. Então nossa função EndofGame também. Ambas as funções
precisam ser chamadas clicando nos dois
botões em nosso HTML. Faremos isso pegando
nosso botão de início e fim
e adicionando um ouvinte de eventos
para chamar essas funções. Esses botões, com a ideia
do botão de início e fim. Podemos pegá-los agora com o seletor
document.query. Aqui está o hash. Primeiro,
o botão Iniciar. Adicione ouvinte de eventos
para um evento click, que
acionará uma função chamada StarTofGame.
Duplique isso. O segundo é
para o endBTN, que acionará a função
correspondente. Também mova para baixo nosso ouvinte
de
eventos de cima para
mantê-los agrupados. Na verdade, ele só
quer adicionar ouvinte de
eventos para garantir
que isso esteja concluído. Então, antes de
prosseguirmos, podemos adicionar um
log de console em cada uma
dessas funções para verificar se todas
estão funcionando corretamente. O primeiro é começar. O segundo para o fim. Em seguida, pule para o console. Apenas separe os
minutos, então vamos apenas reanexar. Lá vamos nós. De volta ao console e
nossos dois botões na parte superior. Start aciona um
log do console e também termina também funciona. Essa é a Etapa 1 e também
a Etapa 2 cuidada. O próximo é criar
um Booleano GameStarted. Vamos fazer isso no topo
e no resto de nossas variáveis. Deixe o GameStarted, que
será inicialmente falso. Podemos atualizar essa variável
a partir de nossas duas funções. Remova os registros do console e
quando iniciarmos o jogo, GameStarted
será igual a true. Então, dentro da função
EndofGame, GameStarted
será igual a false. Agora, quando, se este jogo
for iniciado ou não, será
realmente útil e em particular, para a função
StarTofGame, vamos fazer
algum trabalho de limpeza como remover qualquer
existente encomendas. Não queremos
usá-lo para
executar acidentalmente este jogo intermediário. Podemos retornar dessa
função se isso for verdade. Se GameStarted for igual a true, retornaremos
tudo para essa função antes de executar mais código. Depois disso, podemos
passar para remover qualquer pedido
do jogo anterior. Vamos pegar nossos pedidos
e armazenar isso dentro de uma constante com
Document.getElementByClassName. Estamos usando o nome da classe
aqui porque lembre-se, temos essa classe
de order_wrapper. Passe isso entre parênteses. Em seguida, podemos fazer um loop e
remover todos esses pedidos. Se acessarmos o
objeto de matriz principal com um A maiúsculo, poderemos ter acesso
a um método chamado de para criar uma matriz
a partir de todos esses itens. Ao usar
getElementsByClassName, isso retornará
uma coleção HTML. Em seguida, podemos usar isso para criar uma nova matriz a partir desses pedidos. O método from,
passando as ordens. Agora nós temos isso
convertido em uma matriz. Podemos fazer uso de métodos de
matriz, como forEach, para executar uma função
para cada um deles. Passando a função, cada pedido a armazenará
na variável de ordem. Acesse essa ordem individual e chame o método de remoção do
JavaScript. Isso cuida da remoção desses pedidos quando iniciamos um jogo
pela primeira vez, mas também precisamos criá-los em primeiro lugar. Atualmente, temos uma função
chamada CreateOdersList. Se rolarmos para cima para encontrar isso. Apenas para obter essa
função é responsável por criar todos os nossos pedidos. Faria sentido chamar isso
quando o jogo tiver começado. Atualmente, se fizermos
uma busca por isso, podemos ver que isso é chamado apenas de dentro do nosso programa. Em vez de chamar isso
assim que ele for carregado, vamos cortar isso fora
do lugar e depois movê-lo para a nossa nova função
StarTofGame. Agora, todos os pedidos só devem ser exibidos quando o usuário
clicar neste botão Iniciar. Vamos salvar isso
e experimentar isso. Agora, desde que mudamos
nossa chamada de função, não
vemos as
ordens, como começar. Agora eles aparecem
dentro da barra lateral. Os pedidos estão sendo exibidos e
sabemos que essa chamada de função
está funcionando corretamente. Mas não podemos saber se os pedidos anteriores
foram apagados. Onde usamos order.remove. Isso não importa muito
no momento desde todas
as ordens do mesmo. Mas depois vamos gerar ordens
aleatórias que
serão diferentes. Como
medida temporária para testar isso, comente nossa chamada de função. Em seguida, podemos adicionar elementos
temporários em nosso HTML e verificar se
isso está sendo removido. Na seção de ordem de elementos P. Lembre-se de que todos eles
têm a classe de order_wrapper colocada
em qualquer texto dentro. Agora, se salvarmos isso, atualizar, podemos ver toda a execução. Clique em Iniciar. Esse elemento agora
foi removido. Ótimo, então agora sabemos que
isso está funcionando. Podemos remover nossos elementos
temporários e também restabelecer
nossa chamada de função. Em seguida, o próximo passo
é o Número 7 e 8. Isso é para usar a propriedade
style para mostrar e ocultar esses dois botões. No StarTofGame,
na parte superior
da função, use
Document.querySelector. Primeiro pegue nosso botão Iniciar. Acesse a
propriedade style da tela. Podemos ocultar isso
definindo isso como um valor CSS de nenhum. Duplicar e, em seguida,
para o botão final restabeleceremos isso
definindo isso como um valor inline. Copie ambos. Pule para a
função EndofGame e cole-os. Então poderíamos reverter os
valores de ambos. O botão de parada
será exibido com um valor inline e, em seguida, botão
final pode ser removido sem
nenhum. Vamos experimentar isso. Atualizar. Clique em Iniciar e isso remove o botão de término. Clique no final e isso
mostra o botão Iniciar. Você também notará
assim que a página for carregada, vemos esses dois botões. Como o jogo ainda
não começou, queremos mostrar apenas
o botão Iniciar. Vamos mover
isso definindo a propriedade style do
display como igual a nenhuma. Para isso,
já temos o código como nosso segundo valor
dentro daqui. Copie isso e, em seguida, podemos chamar isso na
parte superior do nosso código. Em qualquer lugar ao redor
das variáveis está bom. Atualizar. O botão final
foi removido. Começamos e só
vemos o botão final. Agora estou no jogo. Vemos
apenas o botão de parada.
33. Introdução Ao Javascript Math: Nesta seção,
continuaremos com nosso
projeto Speedy Chef, mas
vamos nos concentrar em algumas funcionalidades úteis de matemática, data e hora
que o JavaScript oferece. A partir de breve,
veremos como podemos usar matemática
JavaScript para gerar pizzas e pedidos
aleatórios. Atualmente, com essa matriz de
ordens que temos, geramos apenas essas
mesmas três ordens cada vez que o jogo começa, mas podemos gerar novas com mais aleatoriedade. Essas ordens continuarão
chegando à medida que o
jogo estiver em execução. Teremos
quantidades diferentes de pizzas e também diferentes tipos de
pizzas para cada pedido. Para fazer isso, precisamos de duas novas
funções na parte inferior. O primeiro
será chamado de GeneratneWorder. Isso será responsável
como parece, por criar um novo pedido
com um número de pedido. Vou analisar isso
, GenerateneWorder. Então esta segunda função será chamada
GenerateNewPizza, e GenerateNewPizza
criará pizzas aleatórias, que serão chamadas
de nossa função de ordem. Teste isso com
um log de console, analisando no objeto matemática
JavaScript. Pouco antes de podermos ver
isso, precisamos chamar nossa função. Então pegue isso e chame
essa função em qualquer lugar abaixo. Atualize, abra isso e isso retorna
muito dentro daqui. Temos muitas
propriedades e métodos diferentes, e eu não sou matemático, então parte disso está
além do meu conhecimento. Mas você não
precisa ser ótimo em matemática para poder
usar um pouco disso. Está tudo aqui para nos ajudar. Existem algumas
constantes que podemos usar, como o valor de Pi, com o
qual você pode estar familiarizado. Temos algo chamado
Random se rolarmos para baixo, que é um método. É o que gera
um novo número aleatório entre zero e um. Temos algo chamado
ceil e andar para arredondar cima ou arredondar para baixo e
veremos isso em
apenas alguns momentos. Existe um método para arredondar
para o número mais próximo. Podemos encontrar o menor
e maior número com min e max, e também muitos outros também. Vamos voltar para
a função e ver como podemos usá-los. Entre no GenerateneWorder, e logo abaixo do nosso log do console, vamos mudar isso
para ser Math.Random, que é um dos métodos que acabamos de ver
dentro do navegador. Vamos testar isso.
Como mencionado anteriormente, isso gerará um novo
número entre zero e um. Portanto, zero está incluído, mas o valor de um não é. Só iremos até o
valor de 0,999 recorrentes. Muitas vezes, precisamos que esse número
seja um intervalo diferente, como o valor de 0-10, 1-50, 0-100 e assim por diante. Para fazer isso, não podemos analisar
em nenhum intervalo para Math.Random. Em vez disso, devemos
multiplicar isso
pelo valor pelo qual
queremos multiplicá-lo. Se eu multiplicar isso
pelo valor de 100, isso nos dará um valor
entre zero e 99. Lembre-se de que zero e um
é o matemática original. RANDOM. Mesmo multiplicar esse 0 por
100 ainda nos dará 0. Como 0,99 é o valor mais alto, multiplicar isso por
100 nos dará o valor de até 99. Salvar. Deixando-nos com alguns números maiores
dentro do console. Vamos armazenar isso
dentro de uma constante. Posso retirar isso do nosso registro do
console, const aleatório. Então podemos arredondar esse número aleatório para o número inteiro
mais próximo. Foi um exemplo. Em
vez de obter 53,4, podemos arredondar isso para 54. Fazemos isso
acessando, novamente, o objeto matemática
JavaScript, um método que acabamos de ver dentro do console
chamado ceil, onde analisamos em nossas
constantes aleatórias. Agora, cada vez que atualizarmos isso, ele arredondará isso para
o número inteiro mais próximo. Na verdade, temos muita
sorte lá porque temos o valor de
100 no console. Isso ocorre porque a
constante aleatória
original nos dará
um número como 99,9. Então isso arredondará
isso para 100. Com esse arredondamento para cima,
todos os números que começam com zero serão
arredondados para um. Isso deve nos dar um
número entre 1-100. Podemos arredondar para baixo
mudando ceil para andar. Mas você não notará muita
diferença dentro do console. Mas isso arredondará para baixo em
vez de arredondar para cima, mesmo como um número inteiro entre 0-99. Também mencionado quando
olhamos para o objeto matemático eram os métodos min e max
no console. Vamos começar encontrando
o maior valor numérico. Para fazer isso,
criaremos uma nova constante chamada mais alta e definida
igual a Math.max. Math.max vai
receber vários valores. Vamos para 1, 77 e 34. Basta analisar em qualquer
número aleatório dentro daqui e, em
seguida, registre isso no console. No meu caso, 77 é o
valor mais alto dentro daqui. Isso é
retornado no console. Como seria de esperar
de forma semelhante, também
podemos armazenar
o menor valor. Temos Math.min. Faça login em qualquer número
dentro daqui. Registre este no console e ele deve
retornar o valor de um. Isso nem sempre é prático
para envolver nossos números dentro da função max ou
min. Muitas vezes, esses números são
armazenados dentro de uma matriz. Então precisamos acessar
esse array e
descobrir qual é o valor mais alto
e o menor. Bem, para dizer isso, crie uma nova constante chamada
números e armazene isso dentro de uma matriz.
Os números salvos estão bons. Conte
esses. Primeiro de tudo, talvez para reproduzir o que tínhamos acima com o
nosso mais alto, e depois analisar nossos
números para Math.max. Vamos fazer isso e
ver o que acontece. console registra o
valor do mais alto. Você pode estar esperando
obter o valor de 77. Bem, se salvarmos
isso e
atualizarmos, veremos o valor de não um
número dentro do console. A razão pela qual conseguimos isso
é porque dentro
daqui estamos analisando em uma matriz, vez dos valores reais que estavam contidos dentro. Para extrair os valores
dessa matriz e comparar, precisamos usar
o método de spread JavaScript
com base nos três pontos. Atualize, deixando-nos
com o valor correto. Além disso, se você quiser, isso também pode ser
usado com Math.min. Funciona exatamente da
mesma forma e esses são outros métodos e propriedades disponíveis neste objeto matemático, como vimos anteriormente
no console, dependendo de suas necessidades
específicas. Agora vamos colocar
isso em prática
gerando pizzas aleatórias e pedidos.
34. Gerando Novas Pizzas Com Matemática: Podemos usar o que
sabemos agora sobre JavaScript Math para gerar pizzas e pedidos
aleatórios. Primeiro, vamos limpar nossa nova função de
geração de pedidos
do vídeo anterior e pular
para gerar nova pizza. Usamos essa função para gerar uma pizza aleatória da matriz de
nossas pizzas. Para começar, criaremos um número aleatório
entre um e três, para gerar a quantidade
para cada pizza. Lembre-se de criar um novo número
aleatório,
usamos Math.random. Isso gerará um
número aleatório entre zero e um. Mas também queremos fazer
isso entre um e três. O primeiro passo é
usar Math.ceil para arredondar esse valor
, cortar isso. Usamos Math.ceil e dentro dos colchetes passamos
neste número aleatório. Com isso entre zero e um, isso sempre vai
arredondar isso até
o valor de um. Mas queremos o valor de 1-3, que
significa que precisamos multiplicar
esse valor retornado por 3, armazená-lo dentro da
constante chamada quantidade. Em seguida, faça um log do console para
verificar se isso está funcionando. Diga isso, e precisamos
registrar esse valor no console chamando
gerar nova pizza. Altera, atualize 1, 3 e 2. Parece ser todos os números
que precisamos em nosso alcance. Essa é a nossa quantidade aleatória, mas também precisaremos
selecionar uma pizza aleatória. Pouco antes de fazermos
isso, em última análise, o que queremos estar
buscando é criar um novo objeto de pizza, const pizza. Esta pizza precisa absorver
a quantidade que você
já criou logo acima e também
precisaremos de um nome de pizza. Este é um passo que agora
precisamos criar. Comente isso para que não
recebamos erros. Tomamos constante
para guardar isso, para todos em pizza aleatória. Isso selecionará uma pizza aleatória do
nosso conjunto de pizzas. Lembre-se de que os arrays sempre
começam com o valor de zero e ele
precisa ir até o
final da nossa matriz. Agora vamos pegar
isso com pizzas.length. Usando um
exemplo semelhante acima, copiaremos isso sem o
ponto e vírgula, passaremos isso. Como sabemos, isso
retornará um valor de 1-3, mas precisamos de um valor de zero até pizzas.length. Para obter zero, usamos Math.floor, que atualmente
nos dará o valor de 0-2. Mas em vez de
multiplicar isso por 3, multiplicaremos isso pelo
valor de pizzas.length. Isso também significa que, se
adicionarmos novas pizzas no futuro, isso também será cuidado. Agora, de volta a esta propriedade name, podemos definir isso igual
à nossa pizza aleatória. Mas lembre-se, nossa pizza
aleatória está selecionando uma da matriz. Se olharmos para a matriz, isso contém um objeto
com o nome, o método e as etapas necessárias. Só precisamos acessar
a propriedade name, que possamos acessar
Randompizza.name. Finalmente, já que o
trabalho de gerar nova pizza é
gerar nova pizza. Isso é o que
fizemos com esse objeto, para que possamos retornar isso de
volta da nossa função. Bom, vamos experimentar isso.
Em vez de chamar isso diretamente na parte inferior,
coloque isso em um log de console,
gere nova pizza. Chame essa função, atualize
como nosso primeiro objeto. Temos uma quantidade aleatória de três e o nome de
presunto e abacaxi. vez, um vegetariano, dois vegetarianos
e uma galinha. Isso é efetivamente metade
do trabalho feito para
gerar nosso novo pedido. Temos todas as
pizzas de volta. Mas em vez de
login no console, esse valor, precisamos chamar isso de
gera um novo pedido. Entre nessa
função e
começaremos criando uma nova
variável de pizzas e definiremos isso
igual a uma matriz vazia. Esta matriz de pizzas vazia
será usada para construir uma quantidade aleatória de
itens para o nosso pedido. Porque lembre-se,
mesmo gerando nova pizza, ela gera vários valores, ainda
é apenas um item de linha. Com isso, se atualizarmos,
inicia-se novamente. O que quero dizer com isso,
se clicarmos em uma de nossas ordens é, por exemplo, geramos apenas em uma linha, como um presunto e
abacaxi ou dois pepperonis. As pizzas armazenarão uma variedade de todos
esses itens de linha. Neste jogo,
vou restringir o número de
itens de linha até cinco, então não temos
muitos pedidos enormes. Já sabemos como
gerar um novo número
entre um e três. Vamos copiar isso, armazenar isso dentro de uma constante
chamada item de pedido, em vez do valor de
três, alterações para cinco, dado um número
entre um e cinco, que você pode alterar
se preferir. Agora sabemos que
temos um número aleatório entre um e cinco. Em seguida, criaremos um loop para
empurrar cada um de nossos pedidos, que é gerado a
partir dessa função para nossa matriz de pizzas. Repetiremos isso para
o valor do item do pedido. Passe em um loop for, eu vou
ser inicialmente definido para um. O loop continuará sendo executado
onde i é menor ou igual ao
valor acima do item do pedido, então isso é 1-5. Depois de cada loop, vamos
incrementar i com i plus plus. Para nossa matriz de pizzas vazias, use o método push
para adicionar um novo valor. O novo valor a ser empurrado é esse valor que é
retornado da geração de nova pizza. Devemos ficar com
agora uma matriz de pizzas, que é definida para uma série de itens de
linha entre um e
cinco e , em seguida, os objetos de
pizza aleatórios dentro. Isso agora nos deixa com nossa matriz de
pizzas para o pedido, mas agora precisamos construir
nossos objetos de ordem. Isso cria uma nova
constante para armazenar isso, chamada nova ordem, deixe que
este seja um objeto. Cada pedido precisa de um ID exclusivo. Poderíamos ir em frente e gerar algum
número ou string aleatório longo. Neste caso, um número de
pedido simples está bom. O que vou fazer é apenas
fora dessa função, criar uma nova variável
chamada número de ordem e definir isso igual ao comprimento do ponto da matriz de
ordens. Se nossa quantidade atual
de pedidos for três, isso retornará
o valor de três. Mas como estamos
criando uma nova
ordem no final dessa matriz, adicionaremos mais um ao final. Deve haver
sempre mais um do que o número de pedidos
que temos. Portanto, será único. Podemos passar isso como ID, colocar na
matriz de pizzas de cima. O que realmente queremos
fazer com esse novo pedido? Bem, no topo, lembre-se de que
temos nossa matriz de pedidos que contém as
três ordens de amostra. Precisamos empurrar para o
final dessa matriz. Isso é bem simples.
Nós pegaremos nossos pedidos.push place
em nosso novo pedido
e, finalmente, aumentaremos nosso número de pedido para a próxima vez, então adicione o número do pedido mais. Isso sempre deve ser único. Vamos pegar nossa
nova função de geração de pedidos, e chamaremos isso
na parte inferior e testaremos isso.
Salve e atualize. Clique em “Iniciar”. Em seguida, temos nossos três pedidos originais
da nossa matriz de pedidos
e, em seguida, uma ordem
aleatória na parte inferior. Temos o próximo
número de índice da ordem quatro. Temos um número aleatório de pizzas e também um nome aleatório. Vamos atualizar e tentar mais um. Encomende quatro, este é um
pouco mais longo e
tem quatro itens de linha separados. Lembre-se, poderíamos ter
até cinco itens de linha. Este é um bom progresso
com o nosso jogo e
vamos construir sobre isso
na próxima lição e gerar novos pedidos após um certo tempo de atraso e também
revisitar JavaScript Math, onde veremos
sorteado com a tela.
35. setInterval: Sabemos que nossos pedidos
estão funcionando e também gerando aleatoriamente
assim que o jogo começa. Mas também queremos que eles continuem vindo ao longo do jogo também. Mas esse JavaScript nos
fornece um método chamado setInterval, e setInterval executa uma função após um certo tempo de atraso. Ele está disponível no objeto
da janela, para que possamos simplesmente
chamá-lo por conta própria. Então, chame setInterval e setInterval aceitará
duas coisas. Primeiro, passamos uma função
que você deseja executar, e poderíamos passar
uma nova função diretamente assim, ou podemos fazer referência a uma função
existente pelo nome. A função que queremos
executar é GenerateneWorder, então passe isso
sem os colchetes, e agora também podemos remover
isso logo acima. Separe-o por vírgula.
Passamos um atraso de tempo, e esse é o atraso de tempo
entre cada chamada de função. Também está em milissegundos, então 3.000 milissegundos
são iguais a 3 segundos. Essa função será
chamada a cada três segundos. Verificamos que isso funciona, movemos para a nossa
função GenerateneWorder e podemos passar em um log de console, colocar na matriz de pedidos. Atualize o navegador.
Após três segundos, veremos um
registro de console com quatro pedidos. Três segundos depois,
vemos cinco pedidos, seis pedidos e assim por diante. Bom. Agora sabemos que isso funciona. Anteriormente, criamos
uma função chamada CreateOrdersList. Vamos
dar uma olhada nisso. Role para cima e aqui estamos. Esta é a nossa função aqui. Essa função pegou
a matriz de ordens. Em seguida, fizemos um loop sobre
cada um de nossos pedidos e colocamos isso em
nossa seção de pedidos. Tudo o que precisamos fazer agora é chamar essa função cada vez
que geramos uma nova ordem. Em vez de nosso log do console, que os colocamos antes, dentro de gerar nova ordem, remova o log do console e substitua-o por
CreateOrdersList. Vamos dizer isso e ver
onde isso nos leva. Atualize o navegador. Depois de três segundos, vemos nosso conjunto de
pedidos chegar. Temos o número 1
até quatro
e, em seguida, nos segundos depois, obtemos um novo lote de pedidos. O problema aqui é, porém, não
adicionamos apenas os novos pedidos que foram gerados, também
adicionamos os pedidos
existentes também. Isso agora nos deixa com dois problemas que precisamos corrigir. A primeira é que
os pedidos estão chegando antes
mesmo de pressionarmos o
botão “Iniciar” na parte superior. O segundo, como
acabamos de ver, só
precisamos
adicionar os novos pedidos em vez de adicionar todos
os existentes também. Corrija esse problema,
podemos limpar todos
os pedidos antes de adicionar nossos
novos a esta seção. Isso pode ser feito acessando
a função CreateOrdersList e limpando a seção de ordem
antes de adicionarmos as novas. Vamos voltar
para CreateOrdersList. Aqui vamos nós no topo. Antes de adicionar nossos pedidos
a esta seção, limparemos isso com
Documents.QuerySelector. Pegue nossa seção de pedidos, HTML
interno e defina isso para uma string vazia.
Vamos experimentar isso. Atualize, dê
três segundos. Há nossas primeiras quatro ordens. Ordem 5, isso está parecendo bom. Pedido 6, ótimo. Todos eles estão
chegando, mas em vez de adicionar todos
os pedidos existentes, estamos adicionando-os ao final daqueles que já
estão lá. A próxima coisa
que queremos resolver é adicionar apenas esses pedidos
à barra lateral depois de
clicarmos no botão “Iniciar”. Para isso, em vez chamar
diretamente nosso
setInterval na parte inferior, podemos remover isso, sair do lugar e envolvê-lo dentro de uma
função chamada OrderStimer. Coloque isso de volta para dentro. Lembre-se, quando clicamos
no botão Iniciar, isso aciona nossa função
chamada StarTofGame. Se localizarmos isso aqui, podemos chamar nossa função, que era o OrderStimer. Vamos dizer isso e experimentar isso. Primeiro, atualize e dê
três segundos e não
devemos ver nenhum pedido
agora na barra lateral. Bom. Isso interrompeu
a carga inicial. Clique no
botão “Iniciar”. Agora nossa ordem está começando a chegar. SetInterval também é útil para criar um
temporizador de contagem regressiva para o jogo,
portanto, ele só é executado por um
determinado período de tempo. Assim que você clicar em
“Iniciar”, começaremos um temporizador de contagem regressiva a partir de uma
certa quantidade de segundos. Para isso, precisamos de algumas variáveis
para acompanhar isso. Salte para o topo, onde temos o resto
de nossas variáveis. O primeiro será
uma constante chamada GameLength. Defina isso igual a qualquer número de segundos que você deseja. O meu será 300, e o segundo
usando a palavra-chave let, já que atualizaremos
isso, será igual
ao CountDownTime. tempo de contagem regressiva começará no GameLength inicial. Em seguida, reduziremos em um
segundo com setInterval. Inicialmente, definiremos isso
igual a GameLength
e, em seguida, reduziremos isso à
medida que o jogo continua. Também precisamos exibir
isso na tela. Podemos fazer isso com
Document.querySelector. Precisamos encontrar uma
seção que esteja no topo, então ao lado de nossos botões. Esta é a
seção de controle do jogo onde temos o botão de início e
fim do jogo, e também temos um intervalo
com o ID do GameLength. Passe isso, defina o InnerText. Como estamos inserindo
a variável GameLength, precisamos que os backticks digam que o comprimento do jogo é
inserir a variável, que é o nosso número GameLength, seguido pelo texto de segundos. Recarregue e há
nosso texto na parte superior. Agora precisamos fazer duas coisas. A primeira é
criar uma função para deduzir essa variável
em um segundo. Em seguida, podemos chamar
essa função uma
vez por segundo usando setInterval. Primeiro na parte inferior, crie nossa nova função
chamada CountDownTimer, que será responsável por pegar nossa variável, que é contagem regressiva Tempo e
deduzir isso em um segundo. Cada vez que
fizermos isso, também precisamos pegar os mesmos elementos
no topo e atualizá-los
com esse novo horário. Assim como fizemos
no topo, usamos Document.querySelector, passá-lo na mesma seção, que era GameLength,
o InnerText , abra os backticks. Desta vez, diremos que o tempo restante é igual à nossa
variável logo acima. Esta função não
faz nada sozinha. É simplesmente responsável
por selecionar nossa variável CountDownTime e
depois deduzir em um segundo. Para atribuir isso também
à variável existente, também
precisamos
colocar em um igual
e, em seguida, isso adiciona
isso ao DOM. Essa função é
responsável pela dedução em um segundo, mas ainda precisamos chamar
essa função a cada segundo. Para fazer isso, entraremos em
nossa função de início do jogo. Na parte inferior, vamos
setInterval mais uma vez, passar nossa função, que
é o CountDownTimer, que será executado a cada segundo. Vamos experimentar isso. Atualize e veremos nosso texto
no topo. Você pode começar. Então nosso
temporizador começa a contar regressiva. No entanto, se
começarmos isso mais uma vez, você notará um pequeno problema. Se olharmos de perto, a
contagem regressiva não começa no primeiro segundo. Nós clicaremos. Temos que esperar um segundo
antes da contagem regressiva. Isso acontece porque
setInterval
não chamará a função
imediatamente. Em vez disso, ele aguarda o
tempo de atraso primeiro e, em seguida, chama
isso depois. Esta é uma correção bem simples. Tudo o que precisamos fazer é pegar nosso temporizador de contagem regressiva e
ligar para isso uma vez
antes do nosso cronômetro começar. Agora, se atualizarmos, clique em “Iniciar”, nosso
temporizador começa imediatamente. É assim que podemos
usar setInterval, que é um
método realmente útil para aprender, assim como outra função de tempo
chamada setTimeout. Isto é o que
vamos abordar a seguir.
36. setTimeout: SetInterval que
acabamos de ver, chama
repetidamente uma
função ou executa algum código com um
atraso de tempo entre cada chamada. Outro método de tempo que temos disponível é chamado setTimeout. setTimeout para executar uma função ou algum código uma vez
após um atraso de tempo. Podemos usar isso para executar
a função EndofGame quando o temporizador estiver ativo. Parece semelhante ao setInterval. Vamos dar uma olhada nisso no
fundo. Este é SetTimeout,
que, como setInterval, também aceita duas coisas. Primeiro é o código que
queremos executar e, no nosso caso, queremos executar a função
EndofGame. Separe-o com uma vírgula, o tempo de atraso antes de executar esta função novamente
em milissegundos. Então, 2000 é um atraso de dois segundos. Podemos testar esse
trabalho pulando para a função EndofGame
e faça login no console. Qualquer texto, experimente isso. Então, vamos para o fim.
Abra o console. Dá-nos dois segundos e nossa função
agora está sendo chamada. Mas queremos que essa função seja
executada no final do jogo. Assim, podemos definir o
tempo de atraso para ser o mesmo que a duração do jogo. Temos isso armazenado dentro de
uma variável no topo, que é chamado de comprimento do jogo, atualmente definido para ser 300 segundos. É assim que isso funciona
em vez de ter que esperar 300 segundos pela
nossa chamada de função, eu apenas deixo isso para um
pequeno valor, como três. Até o
fundo, agora podemos definir isso como nosso tempo de atraso. Então, como sabemos que
a duração do jogo é em três segundos, com um
atraso de tempo é em milissegundos, o que significa que precisamos converter isso multiplicando
isso por 1000. Ok, vamos tentar isso mais uma vez, atualizar, e depois de
três segundos, nossa função
agora foi chamada. Então, um pouco de limpeza antes
de seguirmos em frente, removeremos nosso registro do console e a função de fim do jogo. Restabeleça a duração do jogo
para ser em 300 segundos. Bom. Então isso agora funciona bem, mas para salvar esse código de executado quando o
jogo não for iniciado, podemos envolver isso
em uma função. Então crie uma função
chamada GameTimer, coloque isso dentro e essa função agora pode ser chamada quando o jogo
começar. Então, salte para a nossa função de
início do jogo , chame nosso GameTimer. Ainda dentro dessa
função, podemos passar uma mensagem para o usuário. Então, o que vamos
fazer é, se
olharmos para essa área de mensagens, colocaremos em uma
mensagem para dizer: “Chef, nossos primeiros pedidos estão chegando assim que o jogo começar”. Usamos setTimeout
e, em seguida, limpamos isso após uma
certa quantidade de segundos. Portanto, a mensagem não está
permanentemente lá. Para começar na parte inferior, pegaremos a seção
com seletor de consulta. Vamos dar uma olhada
no que o seletor é para essa parte na área de mensagem e temos isso p com
o ID da mensagem. Este é um ID, então use um hash, selecione o conteúdo InnerText. Minha mensagem será “Chef, nossos primeiros
pedidos estão chegando”. Então, logo depois, executaremos
uma função após três segundos para remover essa
mensagem da tela. Mais uma vez, podemos
usar setTimeout. Como já
aprendemos, setTimeout e setInterval podem chamar uma função pelo nome ou podem passar uma
função diretamente. Podemos copiar essa linha
de código, colar isso em. Na verdade, pouco antes de fazermos isso, removeremos esses suportes. Isso precisa ser
definido como igual porque innerText é uma
propriedade em vez de um método. O mesmo para o nosso segundo. Vamos definir este para
ser uma string vazia e, em seguida, logo após nossos
colchetes ou as chaves, podemos adicionar o atraso
de tempo de 3000 milissegundos. Atualize, clique em “Iniciar” e nossa mensagem
agora é colocada
na área de mensagens
e, três segundos depois,
ela foi removida. Bom. Portanto, esta é
uma introdução aos temporizadores
JavaScript usando
setInterval e SetTimeout. Você pode ver como ele pode
ser útil em projetos como esse. Também temos mais
temporizadores para adicionar muito em breve. Mas, em seguida, vamos dar uma
olhada em como limpar esses temporizadores quando eles não
forem mais necessários.
37. Temporizadores de limpeza: Cobrimos
esses dois temporizadores agora que eram setTimeout e também
setInterval desses métodos. Também tenha uma contagem clara parte 2 do CleartimeOut e
também ClearInterval. Esses métodos claros interromperão os temporizadores quando
não precisarmos mais deles, e isso é útil para
quando o jogo acabar. Podemos parar coisas
como a contagem regressiva, para que possamos reiniciar quando necessário. Não use nenhum dos
recursos do navegador desnecessariamente. Para poder limpar um temporizador, primeiro
precisamos armazenar o temporizador original
em uma variável. Primeiro de tudo,
teremos nosso OrderStimer, que contém nosso setInterval. Fazemos referência a isso dentro uma variável chamada OrderTimerRef, que é igual a
uma string vazia. Agora, para esta próxima função,
temos o CountDownTimer, e dentro disso não
contém um tempo limite diretamente. Mas se dermos uma olhada primeiro, este é chamado
usando setInterval. Vamos colocar disponível
logo acima disso. Este é o
CountdownTimerRef. Também uma string vazia. último é o GameTimerRef. Observe aqui como declaramos essas variáveis à esquerda
fora de cada função. Isso ocorre porque se
os declararmos dentro da função, não
poderemos
acessá-los mais tarde em outras partes do nosso código. Precisaremos
acessá-los para limpar os temporizadores. Vamos abordar isso com mais
detalhes em uma seção posterior. Este primeiro
será igual ao nosso setInterval. A referência do temporizador do jogo é
igual ao nosso setTimeout. Também conheça esse meio,
o CountDownTimerRef, não
contém diretamente nosso tempo limite. O que podemos fazer é ir
até a nossa função, que é este StarTofGame,
e configurar isso lá em cima. Então esta função StarTofGame. Defina o CountDownTimeRef como
igual a setInterval. Agora, todos eles são armazenados
dentro de variáveis. Pouco antes de
esclarecermos isso, primeiro precisamos provar que
eles estão correndo. registro do console pode nos ajudar com isso dentro da nossa função
GenerateneWorder. Função GenerateneWorder,
coloque em um log de console. Na verdade, é bom dentro
daqui, como a ordem. [inaudível] o
navegador e atualize. Comece o jogo. Nosso temporizador
começa a contagem regressiva. Vemos que nossa mensagem agora foi removida após três segundos. Nossos pedidos ainda continuam chegando, e também nosso console
registra aqui também. Mas você notará se clicarmos
em “End”, parar nosso jogo,
nosso cronômetro ainda contar para baixo, nossos pedidos ainda continuam chegando. Para corrigir isso, podemos limpar todos esses temporizadores quando chamamos
a função EndofGame. Dê uma olhada nisso
e, em seguida, nós chamamos o método
ClearInterval, analisando em nosso OrderTimerRef. O segundo
também é um intervalo, então usamos ClearInterval. Este é o CountdownTimerRef. Para o terceiro, nosso cronômetro de
jogo foi um tempo limite. Então, usamos CleartimeOut
para este. Experimente isso mais uma vez.
Atualizar. Começa nosso jogo. Veja a contagem regressiva,
vemos as ordens. Clique no botão “End”. Tudo agora foi interrompido. Se clicarmos novamente
no botão “Iniciar”, tudo continua
de onde paramos. Vemos que o temporizador continua
de onde foi pausado, e também os pedidos
continuam chegando de onde pararam também. Mas isso é bom,
faremos alguns trabalhos de limpeza muito em breve para corrigir esses problemas. O principal aqui é que nossos
temporizadores agora podem ser interrompidos, quando eles não são mais necessários.
38. Introdução À Data De Javascript: Muitos aplicativos e sites exigem estar ciente
da data atual. Podemos rastrear a data de inscrição de um
usuário, a hora entre dois eventos e muito mais, mas esse JavaScript
tem alguns
objetos internos que podem nos ajudar. Para começar, podemos chamar
data como uma função, assim,
com os colchetes. Em seguida, armazene isso
dentro de uma variável, essa data é igual à
nossa função de data. Então, vamos tentar isso
com um registro de console. Coloque na variável data
e veja o que acontece. Atualizar e entrar no console, que retornará a data atual e também
a hora como uma string, assim como a função de
construtor, que analisamos
anteriormente ao criar novo objetos que coloquei
na nova palavra-chave. Com a nova data, também
podemos passar alguns valores para criar
uma data diferente também. Salte para os colchetes
para que possamos passar no ano, o número de índice do mês
atual,
o dia , as horas, minutos,
segundos e milissegundos. Estamos colocando qualquer
ano que quisermos, depois o índice do mês, que também começa em zero. Janeiro é zero e
dezembro é 11. Em seguida, a data. Salve e atualize isso dentro do console. Isso agora reflete uma data em
que acabamos de colocar. Isso significa que esta função de
construtor, nos dá a
opção de obter a data atual ou definir qualquer data que
desejamos, assim. Trabalhar com valores de data
como esse pode ser difícil. Se quisermos comparar
duas datas diferentes, o que talvez precisemos
fazer é pegar a string atual como
temos no console, dividir nossa string e depois comparar cada peça individual. Como você pode imaginar, essa não
é uma tarefa fácil. Um formato de data alternativo é
usar um método chamado agora. Podemos mover o
conteúdo da data. Com a nova palavra-chave, chame-a agora de método. Vamos experimentar isso e ver
o que acontece no console. Isso nos dá de volta um número
estranho. Pode parecer um pouco estranho, mas é um número em
milissegundos desde 1º
de janeiro de 1970 UTC. Se continuarmos atualizando,
cada vez que fizermos isso, esse número
continuará aumentando. Embora ainda não seja ideal, pode ser uma maneira mais simples de
comparar datas ou horários. Por exemplo, quando um usuário se
inscreve em nosso site, poderíamos usar o Date.Now para armazenar a
hora atual em milissegundos. Em seguida, em futuras visitas, podemos obter a
hora atual e comparar a diferença entre
esses dois números. Os milissegundos precisariam
ser convertidos em segundos, minutos e dias também, dependendo do que você
precisava fazer com ele. Vamos ver isso com
um pouco mais de detalhes em um próximo vídeo. Disponível no
protótipo de datas há uma variedade de métodos que podemos usar
para também definir a data. Vamos dar uma olhada
neles no console. Poderíamos mover o método now. Acesse o objeto protótipo, atualize e abra esse objeto. Como acabamos de ver,
temos a
função de construtor de data e muito mais casos
de uso também, como obter as horas, obter a data completa, obter o dia. Também temos os setters, para que possamos definir a
data atual, podemos definir a hora. Não vou passar por
tudo isso, pois eles são muito específicos para
diferentes casos de uso, mas funciona como
qualquer outro método. Use-os já que os métodos
estão em objetos. Mais uma vez, precisamos usar
a nova palavra-chave para criar um novo objeto de data. Vamos remover isso, colocar entre colchetes, adicionar
a nova palavra-chave. Um dos métodos que
acabamos de ver
no console foi GetMonth. Temos isso em
nossa variável de data. Vamos ver o que
retornou dentro do console. Isso retorna a data
do mês atual. Novamente, isso começa com zero, então janeiro é zero, e fevereiro é o
número 1, e assim por diante. GetDay retornará a
data da semana atual. Vamos tentar isso.
GetDay. Isso é o que você já viu com
o protótipo antes. Também temos acesso a alguns métodos que também
definem a data. Talvez tenhamos um evento
que já teremos economizado e talvez quereremos mudar o mês ou o ano, que poderíamos fazer
exatamente assim. Aqui, temos a data atual
básica. Vamos apenas remover
isso. Então, abaixo disso, vamos mudar
o mês atual para qualquer coisa que
você queira. Vamos armazenar isso dentro de uma constante chamada data atualizada. Pegue nossa variável de data atual, acesse um de nossos
métodos definidos, como setMonth, coloque um número de índice de 11, que será dezembro. Em seguida, um segundo registro do console logo abaixo, novamente com a data. Devemos ser capazes de ver
a versão atualizada com nosso segundo log. Atualize isso. Começamos com março e, em seguida, definimos nosso mês para depois dezembro. Esta é uma introdução básica
à data do JavaScript. Em seguida, faremos uso
dessa data e hora
dentro do nosso projeto, acompanharemos quanto tempo as
pizzas estão no forno.
39. Definir o tempo de cozimento: O que aprendemos
no vídeo anterior, a tarefa agora é definir
o tempo de cozimento da pizza usando a data do JavaScript. Vamos
mover os exemplos do vídeo anterior. Agora, dentro da função adicionar
ao forno, criamos uma
data de espaço reservado no início. Vamos dar uma olhada nessa
função, no forno. Aqui definimos o tempo
adicionado para ser uma string. Isso agora pode ser
atualizado para usar
a data atual dinamicamente. Como vimos, acessamos o objeto de data e
o método chamado agora. Lembre-se da data. Agora
será em milissegundos, para que possamos remover isso
do forno após uma certa quantidade de
milissegundos ter passado. Mas primeiro antes de
fazer isso, precisamos
definir o tempo de cozimento
que queremos aplicar. Essa variável é perfeita, então pule para o
resto das variáveis. Configure uma constante
chamada tempo de cozimento, que é igual a 20 segundos. Agora, até o
fundo do nosso roteiro, aqui podemos colocar em uma nova
função que irá percorrer todas as pizzas dentro do forno uma vez
a cada segundo. Em seguida, removeremos todas
as pizzas que estiveram no nosso tempo de cozimento definido. Função, verifique o forno. Para verificar o forno uma vez cada segundo, podemos
usar um intervalo definido. Se você quisesse,
você poderia criar uma
função independente separada ou podemos colocar na
função diretamente. Esta função
vai fazer um loop sobre todos os itens dentro
da nossa matriz de forno. Este conjunto de forno é armazenado
na variável do forno, loop sobre usando para cada um. Novamente, para cada um assume uma função que tem acesso a cada uma de nossas pizzas
individuais no forno. No final de nossos colchetes de
intervalo definidos, podemos colocar em um intervalo de
tempo entre cada uma de nossas chamadas de função, que será a cada segundo. Para cada item ou
cada pizza dentro do nosso loop voltado para uma declaração if. Esta declaração if
vai verificar
a diferença de horário a
cada segundo. Podemos dizer se data, mas agora, qual é a
hora atual em milissegundos, então deduza o tempo de cozimento. Lembre-se de que o
tempo de cozimento é em milissegundos. Vamos converter isso,
multiplicar isso por 1000. Em seu
cálculo atual nos dará o tempo 20 segundos atrás. Podemos verificar se esse
valor é maior do que a propriedade
adicionada pizza.time
atual. Se for, já passou mais de
20 segundos e precisaremos
retirá-lo do
forno. Acesse nosso forno. O método shift,
que removerá
o 1º item da nossa matriz. Também precisamos acessar o
1º item porque lembre-se, o 1º item ficará
no forno por mais tempo. Esse sempre será o próximo
a ser removido. Depois de removermos este
item da matriz, precisaremos redefinir o conteúdo do forno
com a função, que é a exibição de um item, que efetivamente
redesenhará o forno. Também podemos acompanhar aqui
o número de pizzas que
cozinhamos, aumentando uma variável. A variável de pizzas completas, um aumento com plus plus. Ainda não criamos isso, então saltamos para o topo com
o resto de nossas variáveis. Deixe as pizzas concluídas
começarem com o valor de zero, e esta seção
será útil mais tarde quando adicionarmos
início ao nosso jogo. Finalmente, nós realmente
criamos essa função, mas ainda não a chamamos. O que precisamos fazer
é chamar nossa função de
forno de verificação quando
começamos o jogo. Saltando para o início
da função do jogo, coloca em baixo na
parte inferior. Vamos experimentar isso. Atualize a página. Início do jogo. Clique em qualquer pedido, adicione isso ao forno,
adicione mais alguns. Dê 20 segundos,
e nossa pizza deve começar
a ser removida. O primeiro se foi, ou
o 2º logo depois. Seguido pelas duas
últimas pizzas.
40. Introdução À Canvas E Co-Ordinates: Ainda podemos ficar dentro do
nosso projeto para este e dar uma olhada em alguns
exemplos na parte inferior. Este vídeo abordará alguns
dos conceitos básicos da tela. Então, no resto
desta seção, vamos desenhar nossas pizzas e mostrar as diferentes
coberturas à medida que as adicionamos. Primeiro, vamos abordar uma parte
essencial e isso é entender
o uso de coordenadas. Existe um elemento HTML
chamado Canvas que
nos permite desenhar para ele
usando JavaScript. Definimos a largura e a
altura da tela
e, em seguida, podemos navegar por
essa grade semelhante a pixels usando coordenadas. O eixo x corre da esquerda para a direita e o eixo y corre
de cima para baixo. Usando essas posições x e y, podemos nos mover para qualquer local
na tela e x,0, y,0 é o canto superior esquerdo. Podemos então passar ou descer qualquer quantidade que quisermos, exatamente
como vemos neste exemplo, onde x é igual a 10
e y é o valor de 3. Em breve veremos como entender essas coordenadas é essencial para desenhar na tela. De volta ao nosso projeto e
em nosso arquivo HTML. Já temos
elementos de tela configurados. Se dermos uma olhada na
nossa área de cozinha, tenha esses elementos de tela
com o ID da área de pizza. Tem a largura de 250 e também a altura de 250 pixels também. Entre em nosso roteiro e vamos até o
fundo do nosso roteiro. Crie uma constante chamada tela
para armazenar isso dentro do. Assim como qualquer outro elemento, podemos usar algo como
document.queryselector. Como acabamos de ver,
podemos passar um documento de identificação. Este é igual a pizza_area. Em seguida, podemos chamar um método
chamado GetContext. Pegue nossa variável, chame
o método getContext. Passando em uma cadeia de 2D. Neste contexto, há
um objeto que contém propriedades e métodos que podemos
usar para desenhar para a tela. Só
precisaremos dos
recursos 2D para esses exemplos. Instale isso dentro de uma
variável ou de uma constante, que geralmente é chamada de CTX, mas isso pode ser nomeado
qualquer coisa que você queira. Ao usar a tela, dois conceitos que
são importantes para entender são traçado e preenchimento. O traço é como uma linha de lápis
ou um contorno e preenchimento, assim como parece, preenche
uma forma com uma cor sólida. Para desenhar um retângulo, temos StrokeRect e também
o método FillRect. Vamos dar uma olhada no
StrokeRect para começar. Embora os recursos desenhados estejam
disponíveis no contexto. Para desenhar o contorno
de um retângulo, usaremos o StrokeRect
e, em seguida, passaremos quatro valores. Os dois primeiros, assim como
vimos nos slides, são a localização x e y para o canto superior
esquerdo do nosso retângulo. Se quisermos que isso
comece no canto superior esquerdo, definimos isso como 0,0. Então temos a largura e a altura do retângulo
que você deseja desenhar. Isso pode ser um
retângulo ou também usado para desenhar um quadrado se estivermos passando valores
iguais. Vamos
dar uma olhada nisso. Vamos dizer isso e
pular para o navegador, dar uma atualização a isso e
vemos o contorno do nosso quadrado de 200 pixels por
200 pixels. Além de também passar valores
codificados
assim. Também podemos acessar nossa variável de
tela de cima. Passe isso e acesse
a propriedade width. Já definimos esses dois
dentro de nossos elementos. Temos 250 pixels para
ambos os valores. Podemos inseri-los
como variáveis. Experimente isso, atualize e,
como isso é 250 pixels, isso agora é um pouco
maior do que tivemos originalmente. Usar essas variáveis é
realmente útil e também podemos fornecer cálculos
com base em seu tamanho. Por exemplo, se quisermos
apenas que isso seja metade da largura da tela, poderíamos dividir isso por 2. Se você quiser que este seja um
retângulo sólido ou um quadrado sólido, podemos mudar o traçado
para ser FillRect. Isso preencherá isso com
a cor preta padrão. O preto padrão geralmente
não parece ótimo, e também podemos mudar
essa cor para isso. Vamos duplicar nossos retângulos e faremos o primeiro
a ser um derrame, e o segundo
vamos fazer isso um pouco diferente. Vamos para 100 por 100. Locais, 20 pixels
no canto superior esquerdo da tela. Agora temos um derrame
e um retângulo preenchido. Podemos fornecer
cores diferentes para cada uma
delas , começando com o traçado. Mais uma vez, acesse o contexto. Já que estamos usando um traço
e passamos no StrokeStyle. Defina isso igual a um
valor semelhante a CSS, como verde. Vou ver que a
cor verde entrou em vigor. Então logo acima do nosso retângulo
preenchido. Também podemos acessar o
contexto e fornecer a propriedade chamada FillStyle para afetar esse segundo quadrado. Isso é igual a qualquer outra cor. Salve isso e atualize. É assim que podemos definir cores
diferentes para cada uma de nossas formas. Isso vem a API também tem um método de arco para ajudar com o
desenho de arcos e círculos. Como sempre, acessamos isso
no contexto ctx.arc. Ao contrário dos quadrados
que acabamos de desenhar todos os retângulos onde o local inicial é
baseado no canto superior esquerdo, com um círculo, isso é
baseado no centro. Podemos acessar a
largura da tela para o eixo x. Divida isso por 2 em
lugares no meio
da tela e também o
mesmo para a altura. Este é o
local de partida do nosso círculo, mas ainda precisamos
fornecer mais informações. O próximo é o
raio do nosso círculo. Se você não estiver familiarizado
com os raios, isso é basicamente metade
da largura do círculo. O valor do
ponto central para o exterior. Vamos para 100. Em seguida, os dois últimos valores
no ângulo inicial e final. Esses valores estão em radianos em
vez de graus. Para começar, adicionaremos
um ângulo inicial de zero e, em seguida, o ângulo final, um valor de dois radianos. Vamos salvar isso e ver o que acontece dentro do navegador. Se recarregarmos, não veremos
nenhum desenho na tela. Isso ocorre porque precisamos
dizer se queremos que isso seja uma linha de traçado ou um
preenchimento sólido como fizemos acima. Logo depois,
acesse o contexto. Segure o método de preenchimento, atualize, deixando-nos com
uma boa curva semelhante a um sorriso. Ou podemos simplesmente fazer a linha
com um traço com ctx.stroke. Você também pode ver que agora
estamos fazendo a linha do traçado. Isso também herdará o estilo de
traçado verde. Para fazer um círculo completo em radianos, precisamos multiplicar
esse valor de 2 por math.pie, que é o grau
equivalente a 360 graus. Há nosso
círculo verde e, como você pode ver agora,
temos um círculo completo. Isso também é colocado
no centro
da tela por causa de
nossas localizações x e y. Pouco antes de
realmente desenharmos isso para a tela usando traçado ou preenchimento, também
podemos definir algumas propriedades
adicionais como a largura da linha
e também a cor também. Vamos começar com a propriedade
line width, que definiremos para um valor de
pixel de cinco. Em seguida, também está disponível no
contexto o StrokeStyle. Esse é o mesmo valor que usamos acima para definir isso como verde. Mas agora vamos substituir isso
para ter uma cor diferente. Antes, eu mencionei que esta é uma propriedade semelhante a CSS,
assim como apenas usando as palavras
como verde ou rosa quente, também
podemos passar
coisas como o valor x e
definir isso como uma cor diferente. Vou para f5cf89. Experimente isso, deixando-nos com uma linha de 5 pixels em
uma cor diferente. Juntamente com esses métodos
para desenhar formas predefinidas, também
podemos desenhar linhas
à mão livre também como uma ferramenta de lápis
se você usou um aplicativo de desenho
no passado. Para demonstrar isso, podemos replicar esse retângulo
ou quadrado externo
verde e desenhar
essa mão livre. Podemos comentar
o primeiro retângulo, que são essas duas linhas aqui. Em seguida, desenhe isso nós mesmos
usando coordenadas. Tudo isso está disponível
no contexto. O primeiro método será MoveTo. MoveTo é basicamente como
pegar nosso lápis, movendo isso para uma determinada parte
do papel que
queremos começar. Isso moverá nossas coordenadas sem realmente desenhar uma linha. Assim como nosso quadrado original, isso começará no
canto superior esquerdo da tela. Para realmente desenhar, usamos
o método chamado LineTo, que desenhará uma linha de
lápis do nosso local inicial para o
local que
definimos dentro daqui. Assim como acima, podemos colocar valores
codificados exatamente como este ou
podemos acessar as variáveis
como canvas.width
e canvas.height. Faça desta uma largura total
da tela para ir direto , acesse a tela.width. Como não queremos
descer no eixo x, podemos deixar isso no
valor de zero. Vamos atualizar. Ainda não vemos a
linha na tela porque precisamos chamar ctx.stroke para desenhar
isso na tela. Esta é a nossa primeira
parte da nossa praça. A próxima parte é
descer e desenhar esta linha vertical a partir da
nossa localização atual, acessar ctx, o LineTO. Ainda queremos permanecer no
lado direito que podemos acessar com a largura de 250 ou,
novamente, usando o
canvas.widthproperty. Passe isso, canvas.width. Então, para descer até a
parte inferior da tela, podemos acessar isso com
lona.height. Duplique isso. Ficaremos com o mesmo valor de
altura de 250. Mas agora precisamos
passar para o lado esquerdo, que é o valor x de zero. Salve, atualize. Só mais
um para ir. Mas agora precisamos subir
para o canto superior esquerdo, que é a posição de 0,0. Bom. Isso é r quadrado
agora na tela, também
podemos adicionar um método
no início,
manter o caminho de início, também
disponível no contexto. Vamos colocar isso
no início logo antes de começarmos a
desenhar nossa forma. Isso é útil
porque limpa
todos os caminhos existentes de cima, então não temos nenhum conflito. Isso também significa que a
posição inicial é lembrada. Podemos usar o caminho fechado para
retornar a esse local
a qualquer momento. Para ver isso, podemos remover
nossa última linha, atualizar. Em vez de desenhar isso manualmente, agora
podemos retornar ao nosso local inicial
com ctx.closepath. Ele deve funcionar exatamente
da mesma forma que antes, retornando ao local
original. Além de criar quadrados,
retângulos, círculos e também desenho à mão livre, também
podemos escrever texto
na tela também. Primeiro, podemos definir a fonte
que queremos usar, ctx.font, e definir isso
igual a uma string. A string pode ter
o tamanho
das fontes e também
a família de fontes também. O método para desenhar nosso
texto é CTX.fillText. Como você provavelmente
adivinhou, também há um método
StrokeText correspondente também. O primeiro valor é uma
string do nosso texto, eu apenas digo Canvas API. Em seguida, um local x e y, que é a linha
de base do nosso texto, então 20 e 200, Salvar e Atualizar. Há nosso texto e também é rosa porque herdará a propriedade FillStyle anterior, que terá de cima. Canvas também pode ser usado para
muitas outras coisas também, e também outros
métodos que podemos explorar e também até adicionar imagens
à tela que
podemos editar acessando
os pixels. Nos próximos vídeos, vamos usar uma tela
para criar as pizzas e também exibir as coberturas
que adicionamos na cozinha.
41. Configurando Os Ingredientes: No topo da seção de
script, temos uma
matriz de ingredientes com alguns ingredientes que
precisamos para fazer pizzas. Estas cordas, todas
combinam com os ingredientes necessários nas etapas
necessárias de cima. Então, se formos para a matriz de pizzas, veremos a matriz de etapas necessárias. Isso contém as cordas
que combinam com nossos ingredientes. Se você alterar qualquer uma dessas pizzas para usar ingredientes
diferentes, certifique-se de que a matriz de
ingredientes
também esteja atualizada para corresponder também. Isso será realmente
importante em breve. O que faremos neste
vídeo é
percorrer todos
esses ingredientes e depois exibi-los como
botões na área da cozinha. Depois que uma pizza for selecionada, o chef pode
seguir esse método e fazer a pizza
usando esses botões. Além disso, fazendo uso da tela, cada botão irá desenhar os
ingredientes para a pizza. Vamos agora rolar para baixo até
a parte inferior do nosso projeto e limpar os exemplos
do vídeo anterior. Portanto, não precisamos de nada
como o texto. Não precisamos da seção
à mão livre. Não precisamos do círculo. Não precisa de nenhum desses
quadrados ou retângulos. Mas precisamos manter o
acesso à nossa tela e também ao contexto 2D. Depois disso, crie uma nova função chamada ListIngredients, que irá fazer um loop sobre todos os ingredientes da matriz de cima, e exibirá isso
dentro do navegador. Para acessar nossa matriz de ingredientes. Como esta é uma matriz,
podemos usar o método forEach, que executa uma função para
cada um desses valores. Essa função também
vai absorver um ingrediente que
é cada valor de matriz. Então precisamos criar
um elemento de botão para cada um desses ingredientes. Assim, poderíamos criar um
manualmente ou lembrar, também
temos acesso à nossa função auxiliar
chamada BuildElement. Isso leva em duas coisas. O primeiro é o tipo de elementos que queremos
criar, um botão. O segundo é o conteúdo do
texto a ser exibido. Estes são os ingredientes
da nossa matriz, armazene isso dentro de uma constante
chamada IngredientElement. Então, para nosso estilo, também
podemos adicionar uma classe chamada ingrediente para acessar
nossas constantes e adicionar o
nome da classe do ingrediente. O estágio final
é adicionar isso
ao DOM,
Documents.QuerySelector. O seletor de consultas
que precisamos. Vamos dar uma
olhada na página de índice. Precisamos dessa div com
o id dos ingredientes. Aqui dentro, colocaremos em todo o conteúdo
da nossa matriz. Passe isso como uma string. Usamos AppendChild passando
nossa constante de cima. Então, poderíamos chamar essa nova
função imediatamente. Mas provavelmente
faria sentido adicionar isso à função
GameStart, dar uma olhada
no início do jogo. Dentro daqui, vamos
chamá-lo de baixo. Salve e, em seguida,
vamos experimentar isso. Atualizar. Clique no botão Iniciar e todos os nossos
ingredientes agora estão colocados na cozinha
na parte inferior. Para o próximo passo,
precisamos ser capazes de clicar
em qualquer um desses ingredientes e depois fazer alguma coisa. Esse algo
vai ser uma função para acompanhar as etapas que tomamos
até o fundo. Crie uma nova função
chamada StepComplete. Em seguida, uma segunda função
que vai desenhar os ingredientes para a tela. Função, faça pizza. Esta função StepComplete
precisa ser chamada quando o usuário clica em qualquer um dos nossos
ingredientes logo acima. Então, para isso, pouco antes de
adicionarmos isso ao DOM, podemos adicionar um
ouvinte de eventos acessando nossos IngredienteElements.add
event listener. Isso agora para um clique, que
acionará uma função
chamada StepComplete. Como este é um evento de clique, ele também receberá as informações do evento que
podemos armazenar na variável. Esta
função StepComplete e
agora também pode ser usada para desativar o
botão depois que ele é clicado e também acompanhar
essas etapas que tomamos. Então, a etapa 1
desativará o botão quando o usuário clicar nele. Então, não podemos ser clicados duas vezes. Vou fazer isso acessando nossos elementos com e.target. Podemos definir um atributo. O atributo está desativado
com um valor verdadeiro. Então, passo 2, precisamos acessar o
conteúdo de texto real do nosso botão. Então, saberemos o nome do
ingrediente. Por exemplo, precisamos
pegar o texto da massa de rolo, o molho de pizza ou
o queijo, e assim por diante. Armazene isso dentro de um nome de passo chamado
constante, acesse nossos elementos
com e.target. Em seguida, o conteúdo do texto interno. Antes de prosseguirmos, vamos verificar se isso está funcionando. Coloque em um registro de console.
Temos o nome do passo. No navegador e
no console. Comece o jogo. Clique em qualquer um dos nossos botões, como queijo, molho de pizza. Esses botões também
estão desativados também. Acompanhe as etapas
que tomamos, todos os botões em que
clicamos. Precisamos armazenar isso dentro de uma variável contendo uma matriz. Então, pule para nossas variáveis. Na parte inferior, deixe as etapas
concluídas serem iguais a uma matriz vazia.
Para baixo até o fundo. Agora podemos remover
o log do console, acessar essa variável
de etapas concluídas, acessar o método push
e, em seguida, podemos enviar um
novo valor para essa matriz, que é nosso nome de etapa. A última coisa é chamar
nossa função make pizza para desenhar um novo ingrediente
para a tela. Claro, ainda não
faz nada, mas podemos colocar isso
dentro da função. Então faça pizza. Passe o
ingrediente da pizza do nome do passo. Agora, desde que passamos
em um ingrediente, podemos definir isso dentro
de nossa função e testar se isso está funcionando
com um registro de console. Vamos remover todos os outros registros
do console que temos. Então, temos o invólucro de pedidos, pegamos o forno, o texto da ordem. Em seguida,
atualize, inicie novamente e clique em qualquer um desses
ingredientes. Lá vamos nós. Há nossos novos ingredientes
do log do console de pizza. Isso agora nos deixa
prontos para realmente desenhar certos ingredientes
para a tela. Por exemplo, se a função make pizza
receber molho de pizza, ela desenhará um pouco de
molho vermelho na nossa pizza. Isso é o que
passaremos para o próximo.
42. Desenho de ingredientes circulares: Na parte inferior
do nosso script, atualmente
temos essa função
MakePizza e isso está sendo chamado cada vez que eu adiciono novos ingredientes. Também passou por
esses ingredientes. O que eu gostaria de fazer
agora é criar uma instrução switch para lidar com qual ingrediente
foi clicado. Podemos então desenhar esse
ingrediente em nossa pizza pela tela. Como temos diferentes opções de
ingredientes, como acabamos de mencionar, substituiremos isso por
uma instrução switch para lidar com cada um de nossos casos. Passando o ingrediente
que está sendo clicado
e, em seguida, criaremos
um caso para cada um. O primeiro caso,
isso será uma string e se
rolarmos para cima perto do topo, temos nossos ingredientes
aqui e cada um
dos casos combinará com
cada uma dessas cordas. De volta para baixo, o primeiro em
capitais foi para ROLL DOUGH. Vamos lidar com o que
fazer em apenas um momento, mas por enquanto vamos
sair disso e vamos apenas copiar cada um dos
nossos ingredientes. O segundo caso, este
foi PIZZA SAUCE. O terceiro para QUEIJO,
e depois PEPPERONI. O próximo foi para
HAM e ABACAXI. Vou deixar isso como o conjunto de ingredientes por enquanto e você pode adicionar todo
o resto se preferir, mas vou seguir
em frente porque isso
será muito longo caso contrário. Agora, dentro de cada
um desses casos, podemos configurar algumas funções de desenho de
tela para representar os ingredientes
específicos. Para a massa, para
o molho de pizza e também para o queijo, estes podem ser razoavelmente simples, só
precisamos
desenhar alguns círculos. Começaremos com a massa de rolo. Sabemos de vídeos anteriores
que, para desenhar um círculo
na tela, usamos ctx.arc, então fornecemos o local
inicial que
estará no centro. lona.largura dividida por dois e também a mesma
para a altura. Esta é a posição inicial
x e y. O próximo será
o raio. Vamos por 100 pixels. Assim como antes, para criar
um círculo completo em radianos, a posição inicial
é zero e, em seguida a posição final é duas multiplicadas pelo
valor de Math.Pi. Lembre-se de que, a partir de
vídeos anteriores quando usamos ctx.arc, ele não
desenhou nada inicialmente na tela. O que precisamos fazer
é usar ctx.stroke ou ctx.fill
para desenhar isso, mas na verdade, vamos
realmente usar ambos. A razão é que
usaremos o método de preenchimento para desenhar a base de pizza
completa na tela. Também faremos um método de traçado
adicional, que também adicionará um círculo externo de 15
pixels nesta massa. A razão é
que vamos definir que isso seja uma
cor ligeiramente diferente para
nos dar o efeito
da crosta externa. Primeiro de tudo, o que vamos
fazer é nos concentrar
na crosta e faremos
isso com CTX.LineWidth, defina isso como um
valor de 15 pixels, então vamos definir a cor com StrokeStyle passando em uma
string que será um valor hexadecimal de f5cf89 e para finalmente desenhar isso,
usamos ctx.stroke. Isso agora deve nos dar um
esboço baseado em nosso arco. Vamos experimentar isso, atualizar, começar novamente, selecionar qualquer uma de nossas pizzas, a massa de rolo, e agora vemos o círculo externo da nossa pizza. Como mencionado, esta é a crosta, então também precisamos
adicionar o método de preenchimento para também preencher a
parte interna do círculo, mas uma cor um pouco mais clara
logo após o traço. Coloque a cor do nosso
método de preenchimento e este será f5d69d, depois preencha o círculo
com essa cor. Vamos experimentar isso. Entre
novamente e comece de novo, selecione qualquer uma de nossas
pizzas. Massa de rolo. Não devemos ter essa
cor preta, então vamos dar uma olhada. Este FillStyle realmente só
precisa do hash antes. Comece. Selecione uma de nossas pizzas, enrole a massa e
agora parece muito melhor. Agora, até o nosso molho de pizza, que também será
um círculo, mas um pouco menor que a nossa massa. Não temos
conflitos de cima. Começaremos esta seção
com CTX.BeginPath. Isso também precisa de um círculo, para que possamos copiar o
método ctx.arc de cima, que também
precisará estar no centro da tela. Precisamos
mudar a cor. Isso será preenchido,
então usaremos o FillStyle, e este será ed4434,
finalmente, chame ctx.fill. Em seguida, também
passaremos para o queijo, que ainda é uma função de junção
circular. Copiaremos toda a seção de molho de
pizza, colaremos isso em nossa área de queijo, tornaremos o círculo um
pouco menor para que
ainda possamos ver o molho
ao redor da borda, mas também precisamos
mudar o cor. Este é f7bc4d. Vamos salvar isso e
experimentar isso antes de avançarmos. Mais uma vez, podemos selecionar qualquer pizza, abacaxi, massa de rolo. Isso é bom como vimos. Em seguida, vamos experimentar
o molho de pizza e isso está tudo bem e isso cobre a
mesma seção de preenchimento que a área de massa acima, mas ainda podemos ver o contorno do
traçado de cima. Em seguida, teremos o
queijo, que é um círculo um pouco menor, por isso não cobre
totalmente toda a base de tomate. Bom. Vamos deixar
este aqui por enquanto e no próximo vídeo, vamos dar uma olhada
nos próximos ingredientes, que serão
um pouco mais complexos do que esses círculos. Em vez de criar círculos
como estamos fazendo, vamos envolver várias peças em locais
diferentes. Veremos você no próximo, onde vamos dar uma
olhada em como fazer isso.
43. Desenho de várias peças: Saindo da minha versão
desta declaração de switch, ainda
tenho o pepperoni, o presunto e também as peças de
abacaxi para criar. Como todas essas são peças
separadas, vamos ser desenhadas
muitas formas diferentes em nossa tela em forma de pizza. Para começar, no pepperoni, logo abaixo do estojo, já que estamos usando várias
peças para esses ingredientes, precisamos criar uma
variedade de locais. Const, posições pepperoni, que vai ser uma matriz. Na verdade, isso será
uma matriz de matrizes porque isso será uma matriz de
vários valores. Além disso, cada um desses
valores precisa ter uma localização x e y para
cada uma dessas peças. O primeiro e,
claro, tudo isso precisa ser mantido dentro das
dimensões da pizza. Mas esses são todos números
aleatórios. Podemos adicioná-los e
brincar com eles se você
quiser depois, ou você pode copiar junto com o meu. O terceiro será
147 e 57. Lembre-se de que cada um
desses sub-arrays
será um novo pedaço de pepperoni. O quarto, você pode adicionar
quantos ou poucos esses
quiser,
116, 134,
125, 190, 162, 165, 190 , 190, 190, 85, 192, 142, 150, 115, 76, 95. Quero começar mais
algumas peças. Vamos para 80, 190 e o final, 61 e 135. Certifique-se de que isso seja pouco antes da cláusula break e antes de
fazermos qualquer outra coisa, vamos pensar
exatamente sobre o que precisamos fazer aqui. Um pedaço de pepperoni é
apenas um pequeno círculo. Sabemos como desenhar
isso usando o arco. Mas a diferença
precisará repetir esse arco para cada um desses locais. É aqui que um
loop pode entrar. O que faremos é pegar nossas constantes de posições de
pepperoni. Em seguida, chamaremos um loop para
cada nesta matriz. Passe uma função que recebe o nome da
variável da peça. A peça será cada uma
dessas peças individuais de
pepperoni que vamos desenhar. Para fazer isso, começaremos com CTX.BeginPath sem nenhum caminho existente
que possa ser desenhado. ctx.arc, desenhe cada um dos círculos para
os pedaços de pepperoni. Então lembre-se, isso
leva a localização x e y para o
centro do círculo. Como o que precisa ser
baseado nos locais acima, o que vamos fazer
é acessar nossa peça. A primeira
posição de índice de zero, e para a localização y, será paz e, em
seguida, o número
de índice de um. Passe isso. Peça, acesse o número de
índice zero, a localização y é essa paz
e o número de índice de um, tamanho de 10. Vamos criar um círculo
como zero e depois Math.pi multiplicado por 2. Vamos dar uma cor
com CTX.FillStyle. Pouco antes de desenharmos isso, que é igual a uma string, eu quero ir para o valor
hexadecimal de BD 3611. Então, finalmente, vamos
desenhar isso com ctx.fill, dê a esta nossa cor de fundo
sólida. Vamos tentar isso.
Entre no navegador. Precisamos começar nosso jogo e selecionar qualquer um de nossos pedidos. Além disso, pizza, vamos
rolar a massa, adicionar a fonte, o queijo. Sabemos que isso está funcionando,
ao lado do pepperoni. Há todos os nossos
círculos que são todos baseados em nossa matriz, que criamos dentro daqui. Bom. Agora até
o presunto e você também pode nos dar uma chance se
quiser para si mesmo, você se sente confiante em fazê-lo. Isso será baseado em uma abordagem semelhante à acima. Primeiro, precisamos criar
nossas posições de presunto, que é uma matriz que
também contém subarrays, contém agora as localizações x e y. Vamos primeiro criá-los
e armazená-los dentro de uma constante chamada
HamPositions, nossa matriz principal. Em seguida, crie nossos locais
aleatórios. O primeiro, o
segundo de 108,
74, número 3, 147, 47, 130, 124. Novamente, você pode
torná-los completamente aleatórios e alterá-los se
quiser , 125, 160. Certifique-se de que
tudo isso permaneça
na área da pizza Canvas, 159, 145 ,
197, 82, 202 ,
132, 158 e 90. Estamos quase lá
agora
vamos continuar com os dois finais, faremos 90, 140 e o
último de 105 e 135. Assim como acima,
passaremos por isso com um loop forEach. Selecionaremos nossas posições de presunto chamadas
loop forEach na matriz, que assume uma
função cada peça. Mas desta vez,
em vez de criar círculos usando o método arc, vou usar o método
FillRect para desenhá-los como um retângulo. Primeiro, definiremos uma cor
com CTX.FillStyle, e definiremos isso igual a uma
string, que é f58c8c. Em seguida, CTX.FillRect. Desenhe um retângulo sólido
na tela. Assim como acima, isso
vai assumir as posições x e y, que podemos acessar
assim com nossas posições de matriz x. esta é a peça e o número de
índice de zero, que corresponde a cada um desses primeiros valores de matriz. Em seguida, o segundo valor da matriz da peça que está no número de
índice de um. Lembre-se com retângulos, este é o local x e y para o canto superior esquerdo do
retângulo ou do quadrado, também
precisamos definir o tamanho, que queremos
definir para oito pixels largura , 32 pixels de altura. Vamos experimentar isso antes de
prosseguirmos. Isto é para o presunto. Clique nisso e
temos muitos pedaços de presunto
rosa agora na pizza. Você pode brincar com
as posições se
quiser fazer com que pareça
um pouco melhor. Mas vou passar para o próximo, que
é abacaxi. Para economizar pouco tempo, muito
disso será semelhante à
nossa posição de disso será semelhante à presunto, então vamos copiar toda essa seção,
incluindo o for-loop. Cole isso logo abaixo da
nossa capa de abacaxi. Claro, serão
as posições de abacaxi. Altere-o para o loop. Faça brincar
com esses valores depois, se quiser. Para o FillStyle, mudaremos a
cor deles para ser a cor
amarela do ebe534, tornando-os um pouco
diferentes em termos de tamanho, 12 e 18. Crie as células dentro
do início do navegador. Nossa pizza. O abacaxi
também funciona. Assim como mencionado,
talvez seja necessário mudar sua posição para
que não tenhamos sobreposições. Uma última coisa antes de encerrarmos este vídeo é que também
vamos garantir que os pedaços de
abacaxi e o presunto coloquem na pizza
em ângulos diferentes. Atualmente, parece
um pouco chato porque tudo está voltado para
a mesma direção. Vamos misturar esse ângulo um pouco para cada uma
dessas peças. Podemos fazer isso com girar. Isso começa na seção de presunto. Pouco antes de desenharmos
isso com o FillRect. Podemos acessar a rotação, que também está disponível
no contexto. Esse valor de rotação está
em radianos, não em graus. Uma maneira de converter isso em um
grau é assim. Podemos passar nosso valor
inicial. Se quiséssemos que isso fosse girado por um pequeno valor,
como cinco graus, podemos converter isso em radianos
multiplicando isso por Math.pi dividido por 180. Isso torna muito mais simples
trabalhar com graus se for muito mais fácil envolver
isso dentro de sua cabeça. Mas não queremos manter esse valor
codificado de cinco. O objetivo principal de adicionar
essa rotação para cada uma
dessas peças é torná-la um
valor ligeiramente diferente para cada uma. Podemos adicionar em Math.Random, que colocará em um valor
ligeiramente diferente para cada uma de nossas posições e para
torná-lo um ângulo ligeiramente maior, porque lembre-se de matema.Random
é apenas entre 0 e 1. Podemos multiplicar isso por 2. Isso também é copiar
esse método de rotação, e podemos reutilizar isso
dentro do abacaxi. Pouco antes de usarmos o FillRect, vamos tentar isso, atualizar
e iniciar novamente. O molho de pizza, o queijo, pepperoni, ao lado do presunto. Se você der uma olhada de perto, essas peças estão ligeiramente
fora de alinhamento. Também com o abacaxi também, mas com um abacaxi,
como você pode ver, temos um pequeno problema. É quando usamos
vários ingredientes com valores de rotação. Isso acontece por causa
da rotação na transformação. Quando giramos, a tela
girará a partir da origem da tela, que é 0,0, toda a parte superior esquerda. Se adicionarmos várias rotações, cada uma adicionará à
anterior, que definimos. Nós colocamos um para o presunto, e depois adicionamos
a isso adicionando a rotação para o abacaxi. Podemos corrigir isso
redefinindo a origem de cada novo ingrediente usando algo chamado set transform. Para isso, dentro
da nossa função, farei a função de pizza. Pouco antes das instruções
switch. Queremos chamar essa transformação
ctx.set, que
levará seis valores. Os seis valores serão 1, 0, 0, 1, 0, 0. Esses seis valores diferentes
podem ser um pouco confusos, especialmente porque não são
particularmente agrupados. Podemos ver o primeiro valor de um e o quarto
valor também é um. Ambos se relacionam
com o dimensionamento, o que pode tornar um item
maior ou menor. O primeiro é o dimensionamento
horizontal e o quarto é
um dimensionamento vertical. Não queremos que nenhum
desses valores seja aumentado ou diminuído,
então os mantemos em um, que é o tamanho original. O segundo do terceiro valor
se relaciona com a inclinação. Também não queremos distorcer
nenhuma de nossas peças. Estamos mantendo-os como zero, o que significa nada a ser definido. As coisas em que estamos
interessados são essas duas finais. Estes dois finais
definimos na tradução horizontal e vertical
para voltar a zero. Cada vez que
selecionamos novos ingredientes, a transformação de rotação, que olhará antes
da redefinição de volta para zero, o que significa que não obtemos um acúmulo
desses valores de rotação. Vamos tentar isso com
a transformação agora no lugar. Selecione um pedido. Agora, o que estamos
procurando é o presunto e as peças de abacaxi para voltar aos locais originais. Tudo isso está funcionando bem agora. Como mencionado, você pode criar
mais desses casos para diferentes ingredientes, se preferir ou se quiser
alguma prática extra. A próxima, quando você estiver pronto, verei você no próximo
vídeo, onde iremos
limpar esta tela assim que a
pizza for concluída.
44. Limpar A Tela: Quando terminarmos de fazer a pizza, adicionar as coberturas
e, finalmente,
adicioná-la ao forno, precisamos limpar
o Canvas existente pronto para fazer o próximo. Como você deve ter
adivinhado, criamos uma função que
abordará isso, e faremos isso na
parte inferior do nosso script. Crie uma nova função
dentro daqui para cobrir isso chamado ClearCanvas. A primeira tarefa que vou fazer isso dentro dessa função se
entrarmos no Iniciar aqui e
selecionaremos um de nossos pedidos. Lembre-se, quando
faremos cada uma
dessas pizzas e clicamos
nos ingredientes, ela fica o
botão desativado. O que faremos é selecionar todos esses botões para começar. Vamos fazer um loop sobre
esses botões e , em seguida, removeremos esse atributo
desativado. A primeira é configurar
uma constante chamada etapas. Isso vai
percorrer todos os nossos botões com o
nome da classe dos ingredientes. Document.getElementsByClassName. O nome da classe anexado a cada um desses
botões são ingredientes. Um pouco mais de espaço
para isso e se você se lembrar dos
primeiros vídeos quando usamos getElementsByClassName, em
vez de
retornar à matriz, isso retornará
à coleção HTML. Temos coleções HTML. Não podemos usar nenhum dos
métodos de matriz, como para cada um. O que vamos
fazer é pegar nossos passos e, em seguida,
converteremos isso em uma matriz, o que significará que
podemos usar nosso forEach para fazer um loop sobre cada um deles. Faremos isso com Array.from. Isso criará uma nova
matriz a partir de nossas etapas. Coloque isso em. Agora
temos uma matriz, podemos usar métodos de matriz
como forEach, passar em nossa função. Teremos acesso a cada
um dos elementos. A partir desses, elementos, eles podem remover o atributo que passa
na string de desativado. Agora, ele deve fazer um loop sobre todos os nossos ingredientes e remover o
atributo disabled para que esteja disponível para seleção
na próxima pizza. Em seguida, como vimos no vídeo anterior, às vezes
temos um
problema
em que
temos valores de rotação para
o presunto e o abacaxi. O que vamos
fazer é pegar ou definir transformação no topo
da instrução switch,
que está aqui. Os valores atuais dentro
daqui redefinirão nossa transformação se alguma
rotação existente estiver ocorrendo. O passo final é limpar qualquer coisa que esteja
atualmente no Canvas e nós usamos isso no
passado com CTX.ClearRect. Começamos no canto superior esquerdo do
nosso Canvas, que é
zero, zero e para limpar o tamanho
completo do
Canvas, podemos acessar nossas variáveis com podemos acessar nossas variáveis com tela.width e
também canvas.height. É isso. Essa é nossa
função agora completa. A última coisa a fazer é
chamar essa função
de AddToOven. Selecionaremos isso e daremos
uma olhada na função
chamada AddToOven. Logo em DisplayOvenItems, cole isso em
nossas instruções if. Enquanto aqui também há um passo
rápido que podemos introduzir, que é pegar nossa variável
que está concluídaSteps. Redefina isso para ser uma matriz vazia. Vamos tentar isso.
Atualize o navegador e ele é iniciado novamente.
Selecione um pedido. Atualmente em presunto e abacaxi, então rolamos a massa,
adicionamos molho, queijo, presunto e abacaxi. Adicione isso ao forno e agora nossa tela está
sendo limpa e todos os ingredientes
ainda estão disponíveis para seleção em nossa próxima pizza. Vou tentar mais um,
o pepperoni, adicionar os ingredientes,
adicionar isso ao forno, e tudo isso funciona como esperado. Agora é isso para
o nosso trabalho no Canvas e você pode
brincar com as coisas, você pode estender as coisas, e você pode até adicionar os
ingredientes extras , se quiser. Agora vamos agora passar
para a próxima seção onde
terminaremos este projeto.
45. Pizzas de desperdiçando: Esta nova seção
envolverá o término do nosso projeto. Uma das coisas que
precisamos cuidar é verificar se o chef
completou todas as etapas
necessárias antes adicionar a pizza
ao forno. Então, ou seja se a pizza estiver errada,
ela será desperdiçada. Isso é o que
vamos cobrir agora. Mais tarde, também iremos exibir
algumas estatísticas para o usuário, que possamos acompanhar
essas pizzas desperdiçadas
dentro de uma variável. Vamos subir para o
topo do nosso index.js. Role para baixo até nossas variáveis. Usando a palavra-chave let, crie uma nova variável
chamada WastedPizzas, e vamos acompanhar quantas delas erramos. Em seguida, ele volta para a
parte inferior do nosso script e criaremos uma nova
função para lidar com isso. Configure isso, chame
o WastedPizza. Antes de esquecermos, pegaremos nossa variável WastedPizzas
do topo e aumentaremos isso e usaremos isso com
as estatísticas mais tarde. Em seguida, limparemos todas as etapas
prontas para a próxima pizza. CompletedSteps, redefina isso
para ser uma matriz vazia. Então, finalmente,
chamaremos o ClearCanvas. Esta foi a função que foi configurada no vídeo anterior, que irá
redefinir a tela e também remover o atributo
desativado. Para a página de índice. Dentro da área da cozinha principal, também
temos um botão ao qual
podemos vincular isso. Adicionaremos um EventListener a esse elemento que foi
chamar nossa nova função. Abaixo nossa função
documents.QuerySelector. Este botão. Se dermos uma olhada,
isso tinha o ID do desperdício. Adicione um EventListener, onde ouviremos
o evento click, que chamará
nossa função acima. Vamos experimentar isso, salvar e voltar ao nosso jogo
e começar de novo. Selecione um pedido.
Faremos isso errado, basta clicar neles
na ordem errada. Clique em desperdício. Agora, uma
tela está sendo redefinida e vemos que não temos esse item dentro do forno. Isso agora nos prepara para
o próximo vídeo, onde verificaremos
se o chef
tomou as medidas corretas
para fazer essa pizza. Caso contrário, essa função
será chamada novamente, mas desta vez automaticamente.
46. Etapas de verificação: Esta
função de pizza desperdiçada que acabamos criar também será
útil mais uma vez, porque agora vamos
verificar se o chef
tomou as etapas corretas, ou ou seja, adicionou os
ingredientes corretos a pizza antes de adicionar
isso ao forno. Se eles entenderam isso errado, será novamente, uma pizza desperdiçada. Só para dizer isso, se
entrarmos no nosso jogo, selecione qualquer uma de nossas pizzas. Atualmente, antes de adicionar
qualquer uma das coberturas, podemos clicar no forno e adicioná-lo sem os ingredientes
corretos. Também podemos continuar e
adicionar mais deles também. Para verificar os ingredientes, podemos criar uma nova função. Vou fazer isso logo
após adicionarmos isso ao forno. Dê uma olhada na nossa função
chamada adicionar ao forno, que está um
pouco mais adiante. Já faz algum tempo
desde que vimos este. Isso é adicionado ao forno. Logo depois disso,
criaremos nossa nova função, que são as etapas concluídas. Aqui dentro, também precisamos
pegar o nome da pizza, o qual estamos
comparando atualmente. Podemos verificar se temos
as etapas corretas. Então, passando o nome da pizza, que adicionaremos quando
chamarmos essa função. Esta função
retornará um
booleano verdadeiro ou falso,
dependendo se essas etapas
estiverem corretas ou não. Seu valor verdadeiro ou falso
determinará se
podemos adicionar a pizza ao forno e chamaremos isso da nossa função adicionar
ao forno. Pule dentro da
instrução if onde
verificamos se temos um nome de pizza, crie uma constante para armazenar de volta o valor retornado da nossa função que
veremos em apenas um minuto. Vamos chamar isso pode adicionar ao forno. Lembre-se, este será
um valor verdadeiro ou falso, e isso será
igual à nossa função chamada etapas concluídas. Lembre-se disso também precisa
tomar o nome da pizza, que armazenamos
acima nessa variável. Logo abaixo disso,
criamos em nosso objeto de pizza para
entrar no forno. Agora estamos empurrando isso
para a matriz do forno. Mas pouco antes de
fazermos isso, só queremos
garantir que isso aconteça se a
variável pode adicionar ao forno for verdadeira. O que
faremos é cortar todas essas informações do nosso objeto até
as etapas
concluídas. Passe uma instrução if para verificar se pode adicionar o forno
é igual a true. Se for, cole isso de volta. Nossa pizza agora pode
ser adicionada ao forno. Vamos fazer um teste rápido
e verificar se isso funciona. Entraremos em nossa nova
função e, por enquanto, simplesmente
retornaremos
o valor se verdadeiro. Devemos ser capazes de adicionar qualquer uma das
pizzas atuais ao forno. Vamos tentar isso. Clique no
forno e funciona. Mas agora, se pararmos o
jogo e retornar falso, espero que agora deva impedir todas as pizzas sejam
empurradas para o forno. Vou selecionar um,
e isso agora impede que
toda pizza
entre nesta seção. Isso significa que agora podemos
adicionar algumas condições reais para verificar dentro daqui. Para fazer isso, precisamos pegar
os passos de todos os conjuntos de pizzas. Para começar, precisamos realmente
selecionar nossos objetos de pizza. Aqui fomos passados
pelo nome da pizza e se dermos uma olhada no nosso conjunto de
pizzas no topo. Vamos usar
esse nome para encontrar nossa pizza específica
e, em seguida,
retornar o objeto completo para que possamos acessar essas etapas necessárias. Vamos descer e fazer isso agora. Podemos mover as instruções de
retorno, acessar nossa matriz completa de pizzas
e, em seguida, usar o
método de busca JavaScript para pesquisar através
desse nome da pizza. Para fazer isso,
executaremos uma função para cada um dos itens dentro de nossa matriz e armazenaremos isso dentro de uma
variável chamada pizza. Esse método de busca
retornará um novo valor. Queremos verificar se a
pizza que estamos
acessando atualmente tem uma propriedade name que é igual ao
nosso nome da pizza, e então armazenaremos esse valor
retornado dentro de uma constante chamada objetos de pizza. A próxima coisa a fazer é pegar as etapas desse objeto e novamente armazená-lo dentro
de uma variável ou constante. Este é chamado
de etapas necessárias, e definiremos isso igual
ao nosso objeto de pizza acima. Filtre isso para
salvar apenas as etapas necessárias. Agora, se voltarmos ao nosso objeto de pizza no
topo do script, esta é a propriedade de
etapas necessárias que acabamos de acessar. Esta é uma matriz de
todos os valores. Agora temos todos esses valores necessários para construir uma pizza, e também se você se
lembrar de antes, role para baixo até nossas variáveis. Também temos uma variável
chamada etapas concluídas, que é adicionada à medida que um chef clica em cada um
dos ingredientes. Agora precisamos comparar esses
dois arrays e verificar se todas as etapas incluídas
foram atendidas. Além disso, se pensarmos nisso para uma pizza esteja pronta
para entrar no forno, não só
as etapas concluídas precisam estar corretas, mas também precisam estar
na mesma ordem também. Por exemplo, se eu tiver
a massa, o queijo e o molho naquela ordem
específica, tecnicamente
combinaria com uma margarita. Mas não queremos que a
fonte esteja em cima do queijo ou
da massa
a ser adicionada por último. Podemos verificar isso
usando um método de
matriz JavaScript chamado every. De volta à nossa função, o que vou fazer é digitar essa função
e então podemos falar sobre o que está
acontecendo logo depois. Podemos acessar nossas
etapas necessárias, que é a matriz de todas
as etapas necessárias para criar uma pizza e, em seguida, chamar esse método que acabamos de
mencionar, que era cada. Isso executará uma
função para cada um dos nossos valores de matriz. Passando como argumentos,
o elemento, o índice
e, em o elemento, o índice
e, seguida, retorna um valor, que é se o
elemento for igual às etapas concluídas
como no índice. Além disso, finalmente, vamos
armazenar esse valor retornado dentro de uma constante
chamada etapas de verificação. Só para explicar o que
estava acontecendo aqui, vamos percorrer
todas as etapas necessárias
e, em seguida, armazenaremos isso
dentro do valor do elemento. Por exemplo, na
primeira etapa necessária, que geralmente é a massa de papel, esse seria o
valor desse elemento. O número do índice, é
claro, seria zero. Então, abaixo, verificamos novamente
o primeiro se esse valor de massa de rolo for igual ao primeiro valor
nas etapas concluídas. Se esta pizza tiver sido criada, ambos os valores devem
ser iguais a massa de rolo. No segundo loop,
isso geralmente
seria igual ao molho. Em seguida, verificamos se a fonte é o segundo valor e assim por diante. Cada método retornará
verdadeiro se todos eles forem iguais ou falsos se um
único ou mais falhar. Este é o teste principal
para verificar se a pizza está correta antes de
entrar no forno. Se quiséssemos, poderíamos
simplesmente usar isso como nosso único e apenas verificar, mas
se usarmos isso, o chef não sabe exatamente quais ingredientes
causaram o problema. Ele não saberá se usou
muitos ingredientes, não ingredientes suficientes
ou os errados. Para ajudar com isso,
vou configurar
várias condições para que
possamos dar mensagens de
erro diferentes. Isso passará em
algumas instruções if para realizar algumas verificações. Mas o primeiro,
verificaremos se muitos ingredientes
foram adicionados. Queremos saber se o comprimento
das etapas concluídas é maior que o comprimento
das etapas necessárias. Se as etapas concluídas, o comprimento é
maior do que as etapas necessárias. Se for por enquanto,
vamos colocar em um registro de console e
diremos muitos. Copie isso, cole isso abaixo e altere isso para
o símbolo menor que. Podemos verificar se
ingredientes não foram usados suficientes. Se isso acontecer, dirá que não é suficiente dentro do log do console. O terceiro
verificaremos se ambos os
valores são iguais, então apenas certifique-se de que isso
esteja escrito corretamente. Verificaremos se as etapas
concluídas são iguais às etapas necessárias. Também verificaremos se os
ingredientes estão incorretos. Podemos fazer isso com
nossa
variável CheckSteps e verificar se o valor é igual a false
adicionando uma exclamação. Basicamente, tomamos
a quantidade correta de etapas, mas os ingredientes
estão incorretos, mas isso registrará no console o valor dos ingredientes errados. Vamos verificar isso
no console. Abra as ferramentas do desenvolvedor.
Vamos começar de novo. Selecione uma de nossas
pizzas e vamos
buscar pepperoni, que
é simples. Precisamos rolar a
massa com molho de pizza. Espero que este
adicione muitos ingredientes, clique em muitas opções. Tente adicionar ao forno,
vejo muitos, atualize. Vamos fazer isso
mais uma vez, margarita. Só clicaremos em um
desses ingredientes. No forno, isso não é
suficiente ingredientes
e, em seguida, o terceiro e
último, verificaremos se
incluímos os ingredientes errados com a quantidade certa de etapas. Vamos testar isso. Sabemos que o pepperoni tem
a massa de rolo, tem o molho, o queijo e o pepperoni, então precisamos dar
quatro passos, mas
certifique-se de que estão incorretos. Pepperoni, vou adicionar um
pouco de presunto a isso. Certifique-se de que estamos em quatro etapas. Clique no forno e podemos ver que
usamos os ingredientes
errados. Bom. Temos nossas mensagens e essas também precisam
ser mostradas ao usuário, e podemos fazer isso
se passarmos para o nosso index.html. Vamos dar uma olhada. Para a nossa área de Mensagem, temos esta div circundante e
nossas mensagens para o chef, e depois este p com
o id da mensagem. Poderíamos escrever essas
mensagens diretamente em cada uma de nossas
instruções IF e eu as
colocarei na tela, mas em vez disso vamos criar uma função
autônoma para lidar com elas, já que seremos repetindo essas várias vezes. Vamos adicionar nossa função
chamada ShowErrorMessage. Passe a mensagem que
queremos exibir. se isso for tudo,
selecionaremos nossa área de Mensagem que acabamos de ver dentro
da página de índice com
Document.querySelector. Passe o id da mensagem, defina o conteúdo do InnerText
igual à variável de mensagem. Agora, uma vez que o chef cometeu
um erro, queremos que isso
desapareça após um certo período de tempo e podemos fazer isso
com um setTimeout. Passe isso em que
assume uma função , separada por vírgula. O segundo valor será
o tempo de atraso em milissegundos, então digamos que dois segundos. Abra o corpo da função. Tudo o que faremos dentro
daqui é copiar esta área de Mensagem,
colar isso em. Vamos definir isso como uma string vazia. Agora podemos chamar essa
função chamada ShowErrorMessage e colocar logs
do console logo acima. Cole isso, adicione uma string. Além disso, você usou muitos
ingredientes. Copie isso. O segundo você não
usou ingredientes suficientes, e o terceiro você
usou os ingredientes errados. Vamos experimentar isso. Mais uma vez, faremos o mesmo
teste de antes. Selecione um pedido, então
faremos muito poucos. Você não usou ingredientes
suficientes , então usamos muitos. Isso é bom. Então o
último quando usamos os ingredientes errados,
então pepperoni. Vou adicionar quatro etapas; enrolar massa, molho de
pizza e pimentas,
e lá vamos nós. A última coisa a fazer
é garantir que essas pizzas só adicionem ao forno se os ingredientes
e as etapas estiverem corretos. Atualmente, como
olhamos anteriormente, isso controlado com
esta instrução IF, e isso só será adicionado
ao forno se isso for verdade. Precisamos cortar esse valor
verdadeiro ou falso, devolvê-lo de volta da função
overblow chamada StepsCompleted. Atualmente, esta função está
em execução e estamos fazendo todas as nossas verificações, mas ainda não estamos retornando um valor verdadeiro ou falso, então precisamos adicionar isso
na parte inferior. Só queremos que
isso retorne verdadeiro também se a capacidade do forno ainda não
tiver sido atingida. Anteriormente, configuramos
variáveis chamadas forno e também OvenCapacity que
podemos ver aqui. Eu tenho o forno que
é uma matriz vazia e também a capacidade do forno também. Nós definimos isso para
conter apenas seis pizzas. Também queremos fazer um cheque
para garantir que
não temos muitas pizzas no forno antes de
devolvermos o valor de true. Vamos cortar isso. Adicione uma instrução IF
onde verificaremos se o forno.length é menor que a capacidade do forno, que atualmente
é seis. Se for, retornaremos true, se não retornaremos false. Estamos quase lá agora, mas
também precisamos cuidar
do que acontece se
usarmos os ingredientes errados, porque se estragarmos uma
pizza, também queremos executar nossa função WastedPizza,
que nós criado anteriormente. Podemos fazer isso dentro
de nossas declarações IF. Se usamos
muitos ingredientes esta é uma pizza incorreta, execute nossa função WastedPizza e,
em seguida, volte para fora disso. O próximo passo é o
meio é
verificar se não usamos ingredientes
suficientes. No entanto, não queremos executar
a função WastedPizza porque eles ainda
podem ter a chance de adicionar os ingredientes corretos
depois. Tudo o que fazemos é voltar para fora disso. Para o último em que
usei os
ingredientes errados , queremos novamente executar
a função WastedPizza,
volte para fora disso. Isso agora deve
nos deixar prontos para tentar isso quando criamos a função
WastedPizza
na parte inferior do vídeo anterior.
Vamos dar uma olhada nisso. Isso também limpa a tela também. Sabemos se essa
função está sendo
executada e também saberemos se o valor
de retorno de true foi acionado porque devemos
ver uma pizza no forno, então vamos atualizar
e experimentar isso. Primeiro de tudo, vamos
selecionar o pepperoni. Vou dar uma chance para
os ingredientes corretos : a massa, o molho, o queijo, o pepperoni e este o forno. Isso é bom. O está [inaudível] agora
sendo limpo, então vamos tentar mais um, o
presunto e o abacaxi. Para este, vamos
torná-lo incorreto. Vamos adicionar o
ingrediente errado, então não muitos. Tudo isso parece
funcionar porque esta pizza não é
adicionada ao forno mas a tela na parte inferior
ainda está limpa e pronta
para adicionar uma nova pizza.
47. Cumprindo Pedidos: Quando concluímos todas as
pizzas em qualquer pedido, seria uma boa
ideia concluir
o pedido para que possamos passar
para o próximo. É nisso que vamos
nos concentrar neste vídeo. Pouco antes disso, quero
corrigir um pequeno problema. Esse problema, se
passarmos para o navegador e Iniciar nosso jogo. Clique em qualquer um
desses pedidos. O problema é que podemos
clicar nesses ingredientes antes mesmo de selecionarmos
uma de nossas pizzas. Isso não só deixa nosso projeto um
pouco estranho, mas também significa que não podemos adicionar
uma pizza ao forno porque verificamos esses ingredientes
selecionados contra os clicados na pizza. Para corrigir isso, tudo o que precisamos
fazer é verificar se a seção de pizza atual está definida quando clicamos
em algum ingrediente. Para fazer isso, dê uma olhada
na função StepComplete, então vou fazer uma pesquisa. Este é o que
precisamos, aqui. Primeiro, antes de verificarmos
se uma etapa está concluída, podemos fazer uma declaração if
no topo. Isso vai verificar se
temos uma pizza selecionada. Onde podemos fazer isso,
se formos ao nosso Index.html para
a área da cozinha, aqui, podemos ver que temos esse espaço com o
ID da pizza atual. Quando selecionamos uma
das pizzas ou encomendamos, ela é colocada
nesta seção. Podemos verificar se ele tem algum conteúdo dentro
desses elementos. Fazemos isso selecionando isso
com Document.querySelector. Este é um ID, então
passe o hash. O ID era current_pizza. Poderíamos verificar se há algum texto
interno dentro daqui, ou se é igual a
uma string vazia. Se estiver vazio, temos um problema,
não selecionamos uma pizza. O que vamos
fazer é acessar nossa função chamada
ShowErrorMessage, passá-la em uma sequência de primeiro, selecionar uma pizza em que você
gostaria de trabalhar
e, em seguida, voltamos para fora disso, então não o código abaixo é executado. Vamos fazer um teste.
Podemos ir até o navegador, iniciar nosso jogo e
selecionar um de nossos pedidos. Agora, antes de selecionar
uma de nossas pizzas, tentaremos adicionar ingredientes
como massa de rolo, e vemos nossa
mensagem de erro aqui. A etapa não está mais
marcada como completa como podemos ver pelo fato de que esse botão não está desativado. Agora, para concluir nosso pedido. Para isso, por exemplo,
isso tem três pizzas. Então queremos fazer
todos esses três
e, em seguida, concluir nosso pedido. Agora, para isso, antes de deixarmos
o jogador
completá-lo, seria bom
primeiro verificar se eles
realmente criaram pizzas suficientes para concluir o pedido. passo 1 será armazenar em algum lugar o número de
pizzas em cada pedido. Há muitas maneiras de
abordar isso, mas vou
armazená-lo como um atributo quando criarmos o pedido. Dê uma olhada na função
chamada CreateListOfPizzas , que é esta aqui. Dentro daqui, onde construímos
nossos elementos particulares, temos uma extensão com a quantidade
atual de pizza. Por exemplo, isso pode ser duas margheritas ou um pepperoni. Agora, podemos adicionar a quantidade de cada linha de ordem a uma variável. Vamos criar essa variável logo acima, para que possamos
acompanhar isso. pizzas totais inteiras, e inicialmente definiremos
isso como um valor de zero. Em seguida, redefiniremos isso toda
vez que criarmos nossa lista de pizzas definindo isso
como um valor zero. Então, logo abaixo
disso, podemos adicionar a quantidade atual de pizza
à variável total de
pizzas existente. Só para esclarecer o que
estamos fazendo aqui, se tivermos um
pedido, por exemplo, esta primeira tem três pizzas, esta tem três,
e esta tem quatro. O que estamos fazendo é que
estamos fazendo um loop sobre todas as pizzas
e, em seguida, adicionando essa
quantidade à nossa variável. Então temos esse
total para a ordem, à
qual podemos nos referir no futuro. Como mencionado anteriormente,
usaremos essa quantidade total de pizzas e adicionaremos isso ao nosso
pedido como um atributo. Podemos fazer isso quando
criamos o pedido. Precisamos dar uma olhada
na função chamada CreateSingleOrder,
que fica logo abaixo. Logo abaixo da nossa lista de pizza, o que faremos é
pegar o invólucro de pedidos, definiremos o atributo, que
usamos no passado. O atributo, esse será um atributo personalizado, não
é um dos
internos que já temos. Geralmente, ao adicionar nossos
próprios atributos personalizados, temos o prefixo de dados. Estes são dados, total de pizzas
e, em seguida, o valor, que
é a nossa variável acima que criamos
chamada total de pizzas. O que estamos basicamente
fazendo aqui é cada vez que criamos um novo pedido, estamos adicionando um atributo de dados
chamado data-total-pizzas, com o número total
de pizzas no pedido. Se salvarmos isso,
podemos entrar nas ferramentas
do desenvolvedor e
verificar se tudo está funcionando. Atualize e, em seguida,
inicie nosso jogo. Agora, se selecionarmos
um de nossos pedidos, dê uma olhada na
classe de wrapper de pedidos, e você pode ver que cada um tem esse novo atributo chamado
data-total-pizzas, e a quantidade para cada
um desses pedidos. Isso significa que agora
temos o número total de pedidos que precisamos criar. Anteriormente, se dermos uma
olhada nas variáveis, também
criamos uma
variável chamada pizzas completas para pedido,
que temos aqui. Isso é aumentado cada vez que adicionamos uma nova pizza ao forno, dando-nos os dois valores
que agora precisam ser comparados. Para fazer isso, também
precisamos criar um botão
para concluir o pedido, que o chef pode acionar
dentro da cozinha. Este botão
acionará uma função e podemos definir isso na função de ordem atual
selecionada. Dê uma olhada nisso,
selecione o pedido atual. Vou criar um
botão dentro daqui,
porque é aqui que definimos a ordem atual na qual
estamos trabalhando. Até o fundo, logo
abaixo desta última linha de código, mas ainda dentro
da instrução if, e abaixo disso, e criaremos uma constante chamada
CompleteButton. Desde cedo, temos a
função chamada BuildElement, que criará um
novo HTML novo para nós. O primeiro botão é o tipo de elemento que
queremos criar, que é um botão e o valor que é
o texto completo. Então, podemos acessar este botão, adicionar um nome
de classe complete_btn. Este botão precisa acionar
uma função para que possamos adicionar um ouvinte de eventos, então
completeButton.addEventListener. Bem, agora é para um clique,
que irá acionar uma função que criaremos em apenas um momento chamada
CompleteOrder. Finalmente,
teremos nosso OrderDiv, que é essa seção atual
trabalhando na seção. Nós pegamos isso e, em seguida,
podemos adicionar AppendChild. Passe-o em nosso botão Complete. Vamos testar tudo isso adicionando um alerta simples dentro
dessa função. Crie a função
chamada CompleteOrder. Agora eu alerta com o
texto completo. Vamos entrar no navegador
e verificar se isso funciona. Atualize e clique
em “Iniciar”. Selecione um de nossos pedidos. Há nosso novo botão
Complete que acionará um alerta
quando clicado. Bom. Agora sabemos que isso funciona
e foi acionado, podemos remover esse
alerta e, em seguida, podemos fazer nossa comparação
entre o número total de pizzas no pedido e o número que
criamos atualmente. Primeiro, pegaremos
nosso pedido atual, armazenamos isso dentro de uma
constante chamada CurrentOrder. Vou pegar isso com
Document.querySelector. Agora, como vamos selecionar
a ordem atual em que
estamos trabalhando? Bem, se você se lembra
de antes, quando clicamos
no botão “Iniciar”, todos os pedidos
dentro da barra lateral, se selecionarmos uma desta
classe de order_wrapper
e, em seguida, quando clicarmos em um, ele é movido para a seção
trabalhando em. A seção trabalhando
também tem um ID. Se rolarmos para cima, esta é
a seção, aqui. Podemos pegar o
invólucro de pedidos que está contido dentro desta seção
trabalhando na seção. Podemos fazer isso
transmitindo-o em um seletor CSS. O trabalho na seção, agarrando nossa seção aqui. Então podemos pegar
nossa seção dentro, que tem essa classe
de invólucro de pedidos. Podemos fazer isso assim
como com CSS, usar o símbolo maior que, e com isso sendo uma classe,
usamos o.order_wrapper. Selecione esse pedido armazenado. Lembre-se, dentro
deste pedido, adicionamos o número total de
pizzas para este pedido, dentro de um atributo personalizado. Podemos usar o atributo get, passá-lo no
nome do atributo que demos a este, e isso foi data-total-pizzas. Armazene isso dentro de uma constante chamada
TotalPizzasonOrder. Então, finalmente podemos
fazer nossa verificação abaixo dentro de uma declaração if. Temos o número total de pizzas que deveríamos ter, e também temos a
variável armazenada de pizzas
anteriormente chamadas
completas para o pedido. Podemos verificar se
pizzas concluídas para pedido é menor do que o valor acima chamado
total de pizzas por encomenda, se for, temos um erro, para que possamos passá-lo em
nossa função chamada ShowErrorMessage com o texto de “Você não
fez pizzas suficientes para concluir este pedido”. Em seguida, volte para fora disso. Vamos tentar isso.
Salve isso e atualize. O que precisamos fazer agora
é iniciar nosso jogo. Para o nosso primeiro pedido, isso tem três pizzas, então clique nisso. Agora, se tentarmos adicionar
um ao outro, e vamos buscar o
presunto e o abacaxi. Criaremos o
primeiro. Adicione isso ao forno. Só temos um,
clique em “Concluir”. Agora recebemos a
mensagem de erro dentro daqui. Isso agora tudo
parece estar funcionando. Podemos passar para realmente remover o pedido
quando ele estiver concluído. Logo abaixo da instrução if, queremos pegar
nosso pedido atual que armazenamos de cima e removê-lo
da
seção trabalhando com o método de remoção. Isso realmente removerá
o pedido desta seção, mas isso só
removerá o pedido que inclui o título
e as pizzas, ainda
precisamos cuidar
de remover o botão. A maneira como pode pegar
este botão é lembrar esta função de ordem completa está sendo acionada a partir do nosso manipulador de
clique no botão, para que possamos passá-lo no real, colocar informações
com o evento. Podemos acessar isso
com e.target. Nós armazenamos isso dentro de uma variável chamada botão
Complete. Assim como acima, podemos
acessar essa variável e chamar o método chamado remove para remover
isso do DOM. Também vamos adicionar algumas
estatísticas a este jogo mais tarde, como o número
de pedidos concluídos. Vamos nos
preparar para isso
criando uma variável
de no topo. Com o resto
deles, diremos que pedidos
concluídos sejam um valor
inicial de zero. Em seguida, volte para a nossa função de pedido
completa onde podemos incrementar
isso pelo valor de um, então os pedidos concluídos, mais, mais. Agora, temos esse
pedido concluído, também
podemos redefinir essa
variável chamada pizzas concluídas para pedido. Podemos redefinir isso para
ser o valor zero, então estamos prontos para
o próximo pedido. Vamos finalmente salvar isso e ir ao nosso jogo, e
podemos experimentar isso. Clique em “Iniciar”. O que estamos
procurando é criar a quantidade correta de pizzas
para concluir este pedido. Primeiro, o presunto e o abacaxi completarão isso,
então temos um, e também temos dois
pepperonis para criar sobre isso. Vamos tentar mais um. Devemos agora ter três no
forno e três que também estão associados a esta ordem. Clique em “Concluir”,
e isso agora remove nosso pedido
da área de trabalho na área.
48. Removendo ordens: Ao testar este jogo, até
agora você pode ter
notado um problema, quando clicamos
no botão “Iniciar”, recebemos os pedidos chegando
e, em seguida, quando clicamos
em uma das ordens para movê-lo para o
trabalhando na seção, quando os pedidos são gerados novamente, a mesma ordem ainda é
colocada na lista. Queremos remover o pedido 1
já que estamos trabalhando nisso. Isso acontece para cada
um em que clicamos. Para corrigir isso, poderíamos
remover esse pedido da matriz de pedidos. Para ajudar a identificar em qual
ordem clicamos, podemos adicionar um
atributo de número de pedido a cada um. De forma semelhante, onde
entramos na
função createSingleOrder, lembre-se cedo que adicionamos esse atributo personalizado
chamado pizzas totais de dados. Isso nos ajudou a identificar quantas pizzas totais
estavam no pedido, que pudéssemos comparar isso com
o valor que criamos. De forma semelhante a isso, também
adicionaremos novos atributos personalizados
com o número do pedido, para que possamos identificar em qual
deles clicamos. Se dermos uma olhada
acima, já
temos acesso a esse ID do pedido. Vai ser bem
direto fazer isso. O que vamos
fazer é duplicar essa linha para criar
um novo atributo. Copie e cole este em. Criaremos um novo atributo. Novamente, com o prefixo de dados
personalizado, este é o número do pedido de dados. Passando esse ID de pedido. Então, antes de
prosseguirmos, vamos salvar isso e tentar
isso no navegador, abrindo as
Ferramentas do Desenvolvedor. Esse é o nosso jogo. Agora, se selecionarmos
um de nossos pedidos, este é o seu OrderWrapper. Temos o pedido de
dadosNúmero de um, temos o OrderNumber de 2, 3, 4, 5 e assim por diante. Com isso agora em vigor,
podemos passar para o nosso código e remover esse
pedido da matriz de pedidos. Um bom lugar para fazer
isso será em nossa função chamada
SelectCurrentOrder. Dê uma olhada nisso.
Esta é uma função que é executada quando clicamos
em cada pedido. Usando essa constante
de OrderWrapper, já
temos acesso
ao clique no pedido. Dentro da
instrução if abaixo, podemos recuperar o
atributo do número do pedido do OrderWrapper
e, em seguida, começar a trabalhar
com a remoção disso. Na parte inferior,
começaremos
recuperando esse número de pedido, instalá-lo dentro de uma
constante chamada OrderNumber. Defina isso igual ao
nosso OrderWrapper. Dot GetAttribute. [inaudível] Número do pedido de
dados do cliente. Agora podemos acessar
nosso array de pedidos. Podemos usar o método de
matriz JavaScript chamado Filter, que pode assumir uma função, e para manter isso curto,
vou colocar em
uma função de seta. Em cada ordem,
na variável de ordem. Em seguida, queremos verificar
se o
ID do pedido específico não é igual ao nosso
número de pedido acima. Isso irá
filtrar todos os nossos pedidos e deixar passar
apenas os pedidos que não foram clicados. Isso nos dará
uma nova matriz com todos os valores
, exceto este. O que podemos fazer é definir nossas ordens como iguais
a isso, o que substituirá
a matriz original. Vamos voltar para
o navegador e
experimentar isso . Comece o jogo. Selecione nosso primeiro pedido. Agora vamos regenerar. Agora, quando nossos pedidos agora
são regenerados, não
vemos mais a ordem
1 nesta barra lateral.
49. Atualizando a UI & Estatísticas: Durante a criação deste jogo,
acompanhamos alguns números, como as pizzas concluídas,
as pizzas desperdiçadas e também
os pedidos concluídos também. Agora eles serão usados
para criar uma seção de estatísticas no final
do jogo. Essa área aparecerá no
lugar da seção de método. Então, vamos ocultar esta
seção e
substituí-la quando ela não for mais necessária
no final do jogo. Na verdade, a seção stat
já está dentro da
nossa página de índice. Se entrarmos aqui bem
no topo
da seção principal, temos essa área onde
vamos atualizar todas essas três áreas
com nossas variáveis. Isso também refletirá
nossas funções de início e fim do
jogo e se moverá sobre todas as áreas que estão
mostrando e ocultando elementos em algumas funções
personalizadas. Atualmente, nossa
área de estatísticas não está sendo exibida porque se
entrarmos em nossa folha de estilos, definimos que este seja o tipo de
exibição de nenhum. Vamos entrar na nossa
página de índice e, se dermos uma olhada, ela começará a
função do jogo aqui. Esta área é responsável
por mostrar e ocultar nossos botões de início e término
assim que o jogo tiver começado ou terminado e
também se rolarmos para baixo, ela também adiciona esta mensagem
no início do jogo, que é então removido
após três segundos. Além disso, a
função de fim do jogo restabelecerá
o botão Iniciar e, em seguida,
ocultar o botão Fim. Para refatorar essas
duas funções, logo abaixo do jogo de inicialização, vamos movê-las
para uma nova função chamada UI do jogo de inicialização. Em seguida, role para cima. Cortaremos nossas duas áreas que
estão mostrando e escondendo os botões em nossa interface do usuário. Em seguida, também nossa área de mensagens com o tempo limite definido para isso. Quando isso estiver dentro e
então podemos chamar uma função de interface do usuário do jogo de inicialização logo acima no lugar do
código, que será cortado. De forma semelhante logo
abaixo do final do jogo, crie uma nova função. Este é a interface do usuário de fim do jogo. Agora, o que precisamos
fazer para este é
copiar um recorte
dessas duas linhas na parte inferior,
e estas para a nova função
e, em seguida, chamar isso no lugar. Vamos tentar isso, até
o navegador e clicar
no “Jogo de inicialização”. Isso agora é removido e
vemos o jogo final. Agora, se clicarmos em “End”, o botão Iniciar
agora será exibido. Nada diferente, apenas
um refator para manter nosso código um
pouco mais organizado. Agora também podemos usar essas duas novas funções para
mostrar e ocultar a área de estatísticas. Começaremos com a interface
do usuário do jogo de inicialização no
documento inferior.QuerySelector. Pegue a seção de
método original que
podemos ocultar acessando o style.display e defina isso igual à
string de bloco, duplique isso
e, em seguida, podemos fazer o oposto com nossas estatísticas . Queremos que a
área de estatísticas fique oculta, mudaremos isso para
ser o valor de nenhum. Fazemos isso porque
só queremos que essas áreas de
estatísticas apareçam no final
do jogo, mas
faremos isso agora revertendo esses dois valores,
em vez da interface do usuário do final do jogo, a área do método é vai
ficar oculto para que possamos revelar a área de estatísticas definindo este
como o valor do bloco, salve isso e experimente isso. Vá para o jogo,
vemos a área do método para que
possamos ver exatamente o que estamos fazendo com cada pizza e o jogo e
agora vemos nossas estatísticas. Como vimos antes, essa área de
estatísticas é apenas o HTML, então precisamos
cuidar de adicionar nossos valores variáveis a
cada uma dessas extensões. Entre em nosso index.js dentro do final
do jogo UI
Document.QuerySelector. O primeiro de nossos abrange a ideia de pedidos concluídos, onde podemos definir o
conteúdo do texto interno como igual à nossa
variável com o mesmo nome. Copie e cole isso mais
duas vezes. A seção do meio
foi concluída pizzas. Novamente com o nome da
variável correspondente. A terceira foi a variável de
pizzas desperdiçadas e
pizzas desperdiçadas. Esses
valores de variáveis livres também precisam ser redefinidos no
início de cada jogo. O início da interface do usuário do jogo
redefine todos esses valores. O primeiro foi o pedido
concluído zero, as pizzas concluídas zero e também desperdiçaram pizzas 2. Vamos tentar isso. Precisaremos criar alguns novos pedidos para
iniciar o jogo. Presunto e abacaxi no
forno e pepperoni. Também desperdice algumas
dessas pizzas, então temos algumas estatísticas, encerre o jogo. Não veja nenhuma
atualização nas estatísticas vamos acessar nosso
código e verificar isso. Onde atualizamos
isso? Atualizamos isso no final da interface do jogo. Essas três linhas.
Podemos ver aqui que o editor de texto destacou um problema com os três pontos. Temos pedidos completos
que devem ser concluídos, verifique a variável.
Complete tudo isso. Parece o
caminho certo, o resultado. Pedido número 1, que
é presunto e abacaxi, adicione isso ao forno e,
em seguida, dois pepperonis , complete o pedido. Na próxima, tentaremos
desperdiçar um pedido, adicionaremos um pouco de
pepperoni e presunto, adicionaremos isso ao forno,
isso está sendo desperdiçado. Agora, clique em “End”, veja um pedido concluído,
que está correto. Em termos de pizzas concluídas lembre-se de que esta variável
só é atualizada quando o
forno real terminar de cozinhar. Uma vez que o temporizador, que está
configurado para ser de 20 segundos, somente após o término do
tempo de cozimento isso
será adicionado como
uma pizza completa. Nós desperdiçamos uma pizza
também, então isso é bom. Quase agora feito com este vídeo, temos algumas
coisas para consertar. Se clicarmos no botão
“Iniciar”, veremos exatamente o que é isso. Damos uma olhada na área
da cozinha, temos 11 em
diferentes ingredientes e também o temporizador está em 271 segundos, mas se
clicarmos em “Iniciar”, o tempo continuaremos a
partir daí em vez reiniciar e os ingredientes também
são dobrados. Vamos corrigir esses dois problemas
no início da interface do usuário do jogo. Primeiro, redefiniremos
nossos ingredientes
selecionando a área HTML
com seletor de consulta. Selecione os ingredientes e redefina isso definindo
o innerHTML como igual a uma string vazia. Também cuidará
do temporizador de contagem regressiva
definindo a variável de
tempo de contagem regressiva para ser igual
à duração do jogo. Experimente isso. É
também o jogo, presunto e abacaxi,
adicione isso ao forno. Agora, se terminarmos, iniciamos o
temporizador que foi redefinido. Vemos apenas o único
conjunto de ingredientes. Finalmente, apenas para
finalizar a área de estatísticas, adicionei uma
animação de fade ao nosso CSS. Se entrarmos em nossa folha de estilos, vamos dar uma olhada no desvanecimento. Criando uma
animação simples para desaparecer
na área inicial
no final do jogo. Tudo o que precisamos fazer
é adicionar isso como um nome de classe ao nosso elemento. Para ver a interface do usuário do final do jogo, duplique qualquer uma delas,
pegue todas as partidas. Desta vez, definiremos o
nome da classe como igual a desvanecimento. Bom, vamos nos dar um
teste final dentro do navegador. Comece o jogo, selecione um pedido, complete o
primeiro, pepperoni. Complete algumas
dessas pizzas para
finalmente em nossas estatísticas , encerre o jogo. Bom. Com isso no lugar, agora
vou chamar
esse projeto feito. Mas provavelmente são algumas
coisas que podem ser melhoradas e alguns pequenos problemas que também
podem precisar ser resolvidos. Mas esse projeto é sobre
aprender JavaScript. Acho que
nos deu muito para
praticar e uma boa chance de
mostrar como todas essas
pequenas coisas que você tem aprendido
durante esta aula, todas trabalham juntas para criar
algo muito maior .
50. Introdução Ao Escopo: Uma parte importante, mas
muitas vezes confusa do JavaScript é o escopo. escopo no máximo básico é uma maneira de colocar
variáveis em grupos. Cada grupo permite uma
certa quantidade de acesso. Isso significa que podemos manter
algum controle sobre o que tem acesso
às nossas variáveis. Isso faz sentido
porque as variáveis contêm todos os
nossos dados importantes. Por que queremos que
eles fossem
alterados para acessados quando
não precisam ser. Aqui vemos um exemplo simples. Declaramos uma variável
chamada pontuação. Em seguida, temos uma função
para atualizar a pontuação, registrá-la no console. Tudo está completamente bem aqui. Mas e quanto a isso
, decidimos adicionar um bônus de 10 pontos
à pontuação. Essa variável é
criada dentro
da função e, em seguida,
registra no console. Mais uma vez, não há problemas aqui. O console
mostrará um valor de 11. Os problemas começam
quando tentamos acessar essa variável bônus
fora da função. Isso causaria um
erro com uma mensagem ao longo das linhas de
bônus não está definido. Sabemos que está definido porque
vemos que não está acessível
por causa do escopo. Isso remonta a esses grupos em que
as variáveis são colocadas. Como a
variável bônus é criada dentro da função,
ao contrário da pontuação. Acessar isso é
restrito a todas as funções. Mas, como sabemos com JavaScript,
isso nunca é só isso. Há também algumas outras
coisas que precisamos entender. Pela primeira vez
em muito tempo,
podemos pular para uma nova seção, e isso é o número 9 e depois
pular para a primeira lição, que é introdução ao escopo, que tem um index.html. Para controlar o
nível de acesso a uma variável,
depende de alguns fatores. Como acabamos de ver,
a localização em nosso programa onde declaramos a variável e também o tipo de variável
que criamos também. Podemos criar variáveis
com var, let e const e elas também
têm um efeito no escopo também. Este é o mesmo exemplo
que acabamos de ver, onde declaramos uma pontuação usando a palavra-chave var fora
da função. Então, dentro da função,
atualizamos essa variável. Adicionamos um bônus e, em seguida,
registramos isso no console. Vamos pular para o console. Podemos confirmar o que
acabamos de ver. Abra-nos e
esperamos o valor de 11. Isso funciona porque
a variável de pontuação é declarada no nível superior do nosso programa e isso
não significa que ela precise ser colocada
fisicamente no
topo, assim como está aqui. Isso significa apenas que não está
aninhado ou declarado dentro de outra
coisa, como uma função. Isso significa que está
no escopo global e é acessível globalmente. Se tentarmos acessar
a variável bônus fora da função
de onde ela foi declarada. Não declaramos
dentro daqui. Vamos ver o que acontece
na parte inferior. Registro do console de posicionamento, uma variável de bônus, que retorna um
erro de bônus não está definido. Essa variável bônus
é restrita a
ser acessada somente dentro
dessa função. Porque essa função
também tem seu próprio escopo. Isso pode ser útil para
variáveis quando não, não
precisamos usar em outro lugar. Isso nos dá a segurança de
saber que outras seções do nosso código não podem
modificar esses valores. Esse escopo de função
também significa que
poderíamos criar várias
variáveis com os mesmos nomes, mas dentro de uma função diferente e se precisarmos disso, elas seriam
completamente independentes. Também podemos ver
esse nível de acesso dentro do console do
navegador também. Se removermos primeiro
esta
atualização de log do console para limpar este navegador. Então, se digitarmos a palavra pontuação
dentro daqui e entrar, isso retornará
o valor de um. Isso está correto porque temos o valor inicial
de um e, em seguida, nossa função é executada e aumenta isso para ser
o valor de um. Tudo isso funciona porque
essa variável é global. Mas o que tentamos acessar
nosso bônus, que tem escopo para essa função.
Vamos experimentar isso. Entre e vemos a mesma mensagem de erro que
tivemos no log do console. Junto com essas funções,
essas variáveis globais
também estão disponíveis em outras instruções de
blocos, como instruções for loops
e if. Vamos tentar uma declaração if
logo abaixo da nossa chamada de função. Se a pontuação, coloque em um log de console com o valor da pontuação e isso deve
funcionar conforme o esperado. Isso também se aplica a outras instruções de
bloco também. As instruções de bloco são
basicamente seções envoltas em chaves, então temos a
função que temos aqui. Eu tenho as instruções if, que também tem
essas chaves curly, mas também coisas como
loops e loops while também. Recapitulação. JavaScript
tem o conceito de escopo para nos permitir definir quanto acesso temos a uma
variável como este exemplo, pontuação é declarada na seção
mais externa do nosso código, que
significa que está
no escopo global. Variáveis globais como essa
podem ser acessadas em qualquer lugar, inclusive dentro dos blocos de
código agrupados em chaves, ou seja, funções
e instruções if. O oposto é
verdadeiro, porém, quando
declaramos uma variável
dentro de uma função, isso tem escopo de função e não estará disponível
fora desse bloco. Portanto,
protegendo a variável de ser atualizada ou
removida de outro lugar.
51. Âmbito de aninhamento: Até agora, vemos que o escopo só
parece funcionar de uma maneira, de fora para dentro. As variáveis declaradas na parte superior, como essa variável de
nível global, estão disponíveis dentro
de outras funções ou blocos, como esta
função aqui. Podemos continuar aninhando outras declarações
dentro de outras, e o escopo continua
da mesma maneira. O acesso é passado de
cima e para baixo para cada nível, mas novas variáveis
declaradas dentro de novos blocos ainda são restritas. Você efetivamente não passou volta para níveis mais altos. Quando vemos isso
no vídeo anterior,
onde tentamos acessar essa variável bônus fora
dessa função e
no escopo global. O aninhamento de escopo é chamado escopo
lexical em JavaScript
e em muitos outros idiomas. Vamos dar uma olhada no que
isso parece em ação. Para começar, temos a
mesma configuração que anteriormente. Primeiro, vamos alterar
esse log do console, incluir o texto da função
interna. Fazemos isso para que fique um
pouco mais claro porque
agora
estaremos estendendo esse código, então ainda está dentro
dessa função podemos aninhar um bloco adicional, como uma instrução if. Uma declaração if, onde
podemos verificar se o bônus é verdadeiro, e se for, com base em um novo log do console com o
texto de instruções if dentro. Em seguida, podemos acrescentar ao
final a variável de bônus. Agora estamos dentro de uma instrução de bloco
aninhado. Tentamos acessar
nossa variável
de bônus do nível acima, então o que você
acha que acontecerá? Bem, vamos experimentar isso. Certifique-se de que você estava dentro
da seção de escopo de aninhamento e isso está aberto no navegador. Atualizar. Podemos ver como esperado, o código da função interna será executado porque
não há nada para parar isso. Em seguida, um nível abaixo dentro
da instrução if, não apenas o log do
console é executado, mas também temos acesso
a essa variável bônus. Isso significa que os blocos de
instrução aninhados podem acessar variáveis de um nível externo ou
superior de escopo. Mas e o
contrário? Mas podemos tentar isso
adicionando uma nova variável dentro de nossas declarações mais profundamente
aninhadas, então var bonus2, qualquer número é bom
para este teste e
podemos acessar isso
no nível mais alto, que é essa função interna, escreva adicione o valor de bonus2, salve e
atualize, e agora podemos ver que obtemos
o valor de indefinido. O que significa que podemos ver claramente que isso não funciona o
contrário. Ficamos indefinidos para que o JavaScript esteja ciente de que essa
variável existe, mas é atribuído
um valor indefinido. Como uma
nota lateral rápida, se o bonus2 fosse declarado com
as palavras-chave let ou const, ele lançaria um erro em vez de ter
um valor indefinido. Mas mais sobre este em breve. O aninhamento também pode continuar
tão fundo quanto você quiser. Vamos tentar adicionar uma
nova instrução de bloco, como um loop while. Isso novamente, também tem suas próprias chaves para colocar
o código e criar
um novo escopo interno. Primeiro, vamos remover o bonus2
que você não precisa mais. Podemos remover isso do log
e, em seguida, dentro de nossa seção mais
profundamente aninhada, podemos ir mais longe. Cria uma nova variável chamada números que você
vai fazer um loop e definirá isso como uma matriz de quaisquer valores
dentro daqui. Enquanto loop, também precisamos de um valor
inicial que
podemos armazenar em i. Defina isso como zero. Podemos continuar executando
esse loop while, enquanto i é menor que o
comprimento de nossa matriz, que podemos acessar
com números, a terra dentro do nosso
bloco de código ou nossa seção de escopo. Colocar um novo
log de console com números i, que imprimirá cada um desses números individualmente, então não fique preso
em um loop infinito. Podemos incrementar o
valor de i a cada vez. Vamos testar
isso. Atualizar. Como ele cairá
registros do console aqui. Novamente, a partir desta seção mais
profundamente aninhada, ainda
acessamos nossa
variável de um nível mais alto, e podemos subir
ainda mais longe e testar nossa variável bônus e
experimentar isso dentro de nossa
profundamente seção aninhada. Cole isso, e
há nosso valor de 10. Também saindo do exemplo
anterior, você provavelmente pode dizer
o que vai acontecer
se tentarmos fazer
as coisas ao contrário. Se você criar uma nova variável
dentro desse loop while, então pule para dentro daqui. Mas o log com a
nova variável de bonus3, que é igual a qualquer valor, e então podemos
tentar acessar isso no nível superior
da nossa função, então adicione isso dentro do nosso
console log bonus3, atualize. Lá vemos o
valor de indefinido. É assim que podemos usar o escopo
em seções de blocos aninhadas. Também vimos alguns
exemplos sobre como o escopo só é acessível
de uma maneira. Seções aninhadas,
como nosso loop while, acessam qualquer variável
de um escopo alto, mas não funciona
ao contrário.
52. Bloco & espaço da função: Vá para o próximo arquivo, que é o escopo do bloco e da função. Não ficamos muito confusos sobre o que
vamos ver agora. Eu mantive o mesmo
exemplo de função que anteriormente. Com este exemplo aqui, temos várias variáveis
aninhadas dentro dessa função
em diferentes níveis. As funções se comportam de forma diferente
de outros blocos de instrução. Daqui para frente cada
vez que menciono blocos, estou me referindo ao código
cercado por chaves, como essas instruções if
e também nossos loops. Com uma função como essa, não
podemos acessar as variáveis aninhadas dentro de fora. Se tentarmos colocar um registro de
console logo após nossa chamada de função,
acesse nosso bônus 3. Você vê que o bonus3 não está
definido e também o mesmo para coisas em outros níveis, como
o bônus regular. Também temos o
mesmo problema, mas não
importa se
as variáveis
no nível superior de uma função estão aninhadas dentro de outros blocos. Mesmo se declararmos
essas variáveis usando let ou const, elas
também serão as mesmas. [inaudível] var de deixar os mesmos resultados e
também o mesmo para const. Mudanças de volta para var.
É assim que uma função se comporta. Ele tem seu próprio escopo
e sabemos exatamente onde estamos com as
variáveis declaradas dentro. Mas não é simples
com outros blocos. Se mudarmos isso de uma
função para qualquer um dos blocos, como uma instrução if,
vamos ver o que acontece. Mova a
palavra-chave function e podemos dizer que se a pontuação for igual a 0, lembre-se de que a pontuação é declarada
no escopo global. Ainda temos o console.log para o bônus na parte inferior. Agora, se tentarmos atualizar, também
precisamos remover
nossa chamada de função. Essa variável bônus já
está disponível. Mas e uma variável
profundamente aninhada , como bonus3? Vamos tentar isso. Atualize e
este também funciona também. Podemos ver aqui que
os blocos se comportam forma diferente
às funções relacionadas ao escopo. Isso acontece porque as instruções de
bloco não têm seu próprio escopo. Bem, isso não é estritamente verdade porque é verdade para este
exemplo que vemos aqui. Mas, como desenvolvedor de JavaScript, temos várias
opções
dependendo de como declaramos nossas variáveis. Variáveis declaradas
com a palavra-chave var, que usamos deliberadamente
até agora, sempre se
comportarão assim. Mas usar const ou let
dentro desses blocos
removerá o acesso do lado de fora e
os esculpirá para
o bloco atual. Se quiséssemos ter certeza de que
essa variável de bônus só estava disponível dentro deste bloco e não de fora do
qual temos aqui, precisamos ter certeza de que
declaramos essa variável usando o const ou
o let palavra-chave. Agora vamos experimentar o bônus. Não temos mais
acesso e também, o mesmo para const. Assim como uma recapitulação quando
declaramos variáveis
dentro das funções, não tivemos essa opção
de restringir o acesso ao interior do bloco de funções ou garantir que seja
acessível de fora. Mas quando usamos outros blocos, como uma
instrução if ou um loop, esses blocos nos dão a
escolha de se
queremos usar o escopo dentro ou não.
53. A piscar: No início do curso,
mencionei brevemente um termo
chamado içamento e prometi voltar a ele. Isso é o que
vamos cobrir agora. Já vimos alguns
exemplos de hospedagem. Vamos dar alguns exemplos primeiro
para ver o que está acontecendo. Os arquivos de título nesta seção de
içamento contêm alguns exemplos e o
primeiro talvez familiar. Este foi um exemplo
que usamos anteriormente na seção de funções
e, no topo,
temos dois arrays. Temos o pão e
também os brownies. Em seguida, temos uma configuração de função
em dois estilos diferentes. Temos a declaração da função e também a expressão da
função. Ambos fazem a mesma
coisa que você está verificando se um ingrediente está presente
na matriz selecionada. Por que estou mostrando esse
mesmo exemplo novamente? Bem, observe aqui
como estamos chamando a função no log up do
console
na parte superior antes da criação da função .
Chamamos de cheque. Como nosso código é
lido de cima para baixo, entramos na chamada da
função CheckAllergies antes
mesmo de ser criado, seja
na declaração ou na versão da expressão. Vamos até
o navegador e ver o que acontece com
esse registro do console. Vamos ver se recuperamos um valor
retornado disso. Isso funciona com a declaração da
função, mas e o
contrário? Comentamos a declaração
e restabelecemos a expressão, atualizamos e isso retorna
um erro dizendo que não podemos acessar nossa função
antes da inicialização. Abaixo disso, temos o Exemplo 2, que é uma
versão realmente simplificada do problema. Estamos criando um log
do console e efetuamos login no valor da variável
antes de ela ser criada. Já vimos dentro do console
antes que isso funcione. Acabamos de remover isso
com a atualização de erro. Podemos ver que isso está
funcionando perfeitamente bem. Isso funciona mesmo que
acessemos nossa
variável de nome antes de
ser declarada e fica ainda mais
estranho se tentarmos
reatribuir um valor de nome
antes de ser declarado. Por cima, logo
acima do registro do nosso console. O que vamos
fazer é reatribuir ou atualizar essa variável com um novo valor antes mesmo de
ela ser criada. Isso também funciona. Veremos o novo valor atualizado
no console. Embora esses
exemplos sejam variados, todos
eles estão mostrando
uma coisa fundamental. Muitas vezes, podemos acessar variáveis antes mesmo de
serem declaradas. Isso nos leva a um
termo chamado içamento. Logo antes de
saltarmos para isso, quero mostrar outra
coisa, o que é uma variação
do último exemplo. E na
parte inferior se você tivesse um registro de console passando
o valor da função? Em seguida, declaramos essa
variável sem inicializá-la com
um valor e, em seguida, daremos a isso um valor
no final. Vamos
testar isso. Salve e atualize. Você pode ver esta versão ligeiramente
modificada
retornará o
valor de indefinido. Olhando para esses dois exemplos, pode
parecer muito estranho porque estamos vendo
como podemos acessar variáveis antes que elas
sejam declaradas e também porque ambos os exemplos
são bastante semelhantes. içamento é frequentemente descrito como o processo de JavaScript, pegando nossas variáveis e declarações de
função e
movendo-as para o topo do programa ou para o topo do escopo, que
significa que elas são
declarado e pronto para acessar a qualquer momento
durante nosso código. Isso explicaria muito
do que acabamos de ver. Nenhum código é movido
fisicamente ou
movido para o
topo do nosso programa. É o processo de
nossas variáveis e declarações de
função
serem colocadas na memória no momento da compilação. O
código legível por humanos que você escreve, como JavaScript, pode
ser lido por um computador. Primeiro, ele precisa ser
convertido ou compilado
nos bastidores em um conjunto de instruções que
os computadores podem entender. É durante essa fase de compilação, nosso código é
lido ou passado pela primeira vez. Nossas variáveis e declarações de
função são então armazenadas na memória. Só para esclarecer, durante esta fase de compilação quando este
programa é passado pela primeira vez, variáveis como esta são armazenadas
pela primeira vez na memória, é por isso
que podemos
acessá-las antes pareçamos ter
criou-os. Não há magia oculta nos
bastidores, nem se mova ao redor do nosso código
até o topo do programa. Simplesmente nosso
código sendo lido e uma referência a todas as variáveis e funções armazenadas na memória. Isso explica algumas
coisas de nossos exemplos. Primeiro, se dermos uma olhada neste
exemplo de função na parte superior. O primeiro exemplo, a declaração da
função. As declarações de função
são içadas. É por isso que podemos chamar essa função antes
mesmo de ser declarada, o que estamos vendo
com nosso registro do console. No entanto,
expressões de função não são içadas, e é por isso que vimos
um erro no console. Por exemplo 2, o
primeiro. Como esse nome
de variável de Chris é içado, é por isso que podemos
acessá-lo antes que ele pareça ter
sido criado, embora isso tenha sido diferente
para a segunda versão, que retorna indefinido. Por que você acha que
há uma diferença entre essas duas variáveis? Bem, uma parte importante a entender é o que
exatamente está armazenado. Para entender melhor isso, vamos dar um passo
rápido para o básico de variáveis. Anteriormente, analisamos algumas
dessas palavras-chave relacionadas a variáveis e uma declaração é quando
declaramos uma variável, que você deseja usar
e, em seguida, damos um nome a ela. Uma vez
que passamos um valor real, isso é chamado de inicialização. Você tem declaração
e inicialização. Volte a este exemplo
para nossa variável de função. Aqui nós declaramos
uma variável vazia e depois disso, inicializamos
com o valor de dev. Na fase inicial de compilação, somente a declaração de
variável vazia é içada e
armazenada na memória. No entanto, embora
a seguinte linha que a inicializamos, esse valor de desenvolvimento foi
ignorado neste estágio. Nesta fase, é atribuído
o valor de indefinido. É por isso que vemos
indefinido no console. No entanto, com os
exemplos anteriores desde que inicializamos isso
com um valor de Chris, na fase de compilação, a variável receberá esse valor em
vez de indefinido. Além disso, para tornar as coisas
ainda mais confusas, precisamos lembrar
aqui que estamos usando a palavra-chave var para
ambos os exemplos. Seu comportamento também é diferente com a palavra-chave let ou const. Se mudarmos nosso papel
para baixo para ser deixado, vamos ver o que acontece
dentro daqui. Fazemos login no valor da função, atualizamos e agora,
em vez
do valor de indefinido ser
atribuído a essa variável, agora
receberemos um erro
dentro do console. Esse erro diz que não podemos acessar nossa função antes
da inicialização. Isso ocorre porque quando estamos usando a palavra-chave const ou let, ela primeiro precisa
ser declarada com um valor antes que possamos acessá-la. Se não
atribuirmos primeiro um valor a
ele, ele ainda receberá um valor indefinido nos
bastidores, mas ainda precisamos declará-lo antes de tentarmos
acessá-lo em nosso código. Este pode ser um assunto complicado de
entender especialmente
no início,
porque o içamento se aplica a
todas essas três palavras-chave, aplica-se a let,
var e const. No entanto, var faz
as coisas um pouco diferente como
acabamos de ver. Mas mesmo que você não
entenda completamente o que estava
acontecendo nesta fase, ter um entendimento básico que as variáveis são içadas pode lhe
poupar muitos problemas
no futuro se você executar
em um erro semelhante.
54. Zona Morta Temporal: A zona morta temporal
é algo que soa
mais difícil do que realmente é. A maioria dos conceitos torno dele foi
abordada em vídeos anteriores. Olhando para o código na seção de
script
na parte inferior, temos um
log de console e uma variável. Sabemos que uma variável
criada assim com a palavra-chave var encontrará acesso antes de ser
declarada. Isso ocorre porque a variável é içada para o topo de seu escopo. Podemos ver isso acessando
isso primeiro e colocarei isso dentro do console para que tudo funcione
completamente bem. Mas, como também descobrimos, se usarmos as novas palavras-chave
let ou const, o comportamento é diferente. Outra maneira de ver
isso seria talvez
inicializar uma variável
antes de usá-la. Se removermos o valor e
inicializarmos isso sobre o topo, o nome será igual a Chris. Vamos ver o que acontece
dentro daqui. Ainda temos um erro, pois
estamos tentando acessar nosso nome muito cedo antes mesmo de
ele ser inicializado. Mas e se trocamos
as linhas um e três? Bem, se colocarmos um
na parte inferior e depois movermos
a palavra-chave let para o topo, isso retornará
o valor de indefinido. Isso também é abordado
no vídeo anterior. Se não atribuirmos um valor a uma variável usando a
palavra-chave let antes de
usá-la, ela será inicializada com o valor de indefinido. Const, let e var todos obtêm
um valor indefinido se
não definirmos o valor inicial antes de tentarmos
acessar a variável. A diferença é que var pode ser acessado antes
mesmo de ser declarado, assim como vimos
no vídeo anterior. Como tudo isso se
relaciona com a zona morta temporal? Bem, é simplesmente nome dado
a algo que já
vimos ao usar as palavras-chave
const e let. É o nome de um
período de tempo desde momento em que inserimos qualquer escopo, até quando uma variável
é inicializada ou acessível. Pode existir uma variável, mas ainda não foi inicializada. Se isso acontecer,
diz-se que está
na zona morta temporal e
não podemos acessá-la ou
usá-la como queremos. Se tudo isso soa um
pouco confuso, vamos simplificar um exemplo para tentar dar uma
melhor compreensão. O que vamos
fazer é remover nossa linha superior dado
o log do console e diremos que o nome seja
igual a ser um valor. Se tentarmos isso,
sabemos que isso não funcionará como vimos em exemplos
anteriores. Isso ocorre porque desde o
início do escopo atual, estamos entrando na zona morta
temporal. Vamos adicionar um comentário, a zona morta
temporal começa. Tudo isso está no
nível superior do nosso script, por isso está no mesmo escopo. Ele não está aninhado em um escopo
interno, como uma função ou uma instrução if. Então, quando nossa variável é
inicializada na linha 14, a zona morta temporal atual termina e a variável agora
está acessível. Sua zona inicial e final também acontece com qualquer
outro escopo também. Por exemplo, se isso
estivesse em um determinado bloco, como uma função ou uma instrução if cercada
nas chaves, o mesmo também se aplicaria. Observando este exemplo, pode
parecer que
a ordem do código é o fator determinante, já que a
declaração da variável acontece depois que
tentamos acessá-la no log
do console. No entanto, este não
é o caso. Como mencionado anteriormente, a zona morta
temporal é um período de tempo desde o momento em
que inserimos qualquer escopo, até quando uma
variável é inicializada. É o tempo que é
importante e não a ordem do código, já que a palavra temporal realmente
se relaciona ao tempo. Podemos ver isso se envolvermos
esse log em uma função. Crie uma função sobre o
topo. Digamos que obtenha o nome. Com este console, faça login dentro uma função e, em seguida,
chame nossa função. No entanto, podemos esperar que
isso cause um erro, assim como vimos anteriormente. Observando a ordem do código, o log do console ainda acontece antes de
declararmos nossa variável. É compreensível que você
esteja esperando um erro. No entanto, este não
é o caso porque a função é realmente chamada fora
da zona morta temporal. A zona morta temporal não
é a ordem do código, é o tempo
necessário para tornar essa variável acessível. Há algumas
coisas complicadas para entender aqui e também nos últimos vídeos. Não espero que você obtenha tudo
na primeira tentativa, mas acho
importante saber que essas coisas existem
porque um dia você pode ter um problema por causa
delas e isso pode apenas
fazer você pensar sobre esses conceitos e como eles podem estar
afetando seu código. Como
facilitamos nossas vidas e minimizamos erros? Bem, uma maneira simples poderia
ser colocar const e deixar variáveis no início
do escopo necessário, seja no
topo de uma instrução if, no topo de uma função ou até mesmo no topo
da nossa scripts. Dessa forma, eles sempre
estarão prontos para uso quando necessário.
55. Fechamentos: Quando criamos
funções, elas nem sempre precisam ser funções
autônomas. Em vez disso, eles podem ser aninhados
no projeto inicial. Nesta seção de fechamento, você pode ver dentro daqui
que temos uma área de script vazia. Agora vamos
criar uma função simples para demonstrar o
efeito dos fechamentos. Entre na seção de script e crie uma
função regular aqui. Vou nomear este o
exterior por dentro com uma variável. Vamos dizer que o valor externo. Eu defini isso para uma cadeia de exterior. Agora podemos aninhar uma
função adicional dentro daqui. Vou explodir nossa variável
cria uma nova função. Desta vez com o
nome de interior. Faremos o que fizemos logo acima criaremos uma nova variável. Este pode estar em um valor
igual à cadeia de interior. Então, dentro dessa função
interna,
criaremos dois logs de console. O primeiro será para o
valor do valor interno, que está contido dentro
dessa mesma função. Vamos duplicar isso e
colocar nosso valor externo. Sabemos de vídeos anteriores
que, ao trabalhar com escopo e quando aninhamos o escopo dentro de funções ou
colchetes como esse, ainda
podemos acessar variáveis
criadas em níveis externos, como este aqui. Basicamente, um escopo interno pode acessar variáveis
de um escopo externo. Para
que esta função interna realmente execute e coloque nossos registros de console
dentro do navegador. Precisamos chamar isso de
dentro daqui, chamada nossa
função interna faz com que você esteja aninhado dentro
da função externa. Então, finalmente, chamaremos
nossa principal função externa, também
faremos isso
dentro de um registro de console. Certifique-se de que você está
colocando os suportes. Em seguida, teste isso
pulando para dentro do console. Vemos o interior, vemos o exterior, que são nossos dois registros de console. Então o terceiro
na parte inferior é o valor da nossa função
que é indefinida. Podemos ignorar esse
valor indefinido no momento
porque
não retornamos nada
dessa função. Mas agora sabemos que isso está
funcionando, pois temos nossos dois logs de console, enquanto isso podemos acessar ambas as variáveis de dentro dessa função
interna. Podemos primeiro acessar
o valor interno porque ele é local
para essa função. Também podemos acessar
o valor externo por causa da cadeia de escopo. Escopo ou escopo lexical,
que você mencionou, permite que essa função
interna acesse nossas duas variáveis. E essa função
interna foi retirada dessa configuração
atual. Não estou falando sobre
mover fisicamente a
função interna em outro lugar. Mas, em vez
disso, e se o armazenássemos em uma variável e fizermos
uso dela em outro lugar? Bem, para poder fazer isso, em vez de chamar a
função interna na parte inferior, em vez disso, retornamos, então removeremos isso,
retornaremos o valor de interno. A parte importante a
entender aqui é que estamos retornando a função
interna real. Quando chamamos essa função
externa. Podemos ver isso
dentro do console. Ainda fazemos login
e também executamos isso. Se atualizarmos isso, agora
veremos essa função interna
dentro do console. Tenha comigo aqui neste. O que estamos fazendo aqui
neste estágio é
chamá-lo de externo, que retorna a função
interna. Essa função interna é efetivamente uma
informação independente. Ele não tem referência a essa função externa ou
qualquer conteúdo interno. Vamos pegar esse valor interno, que podemos ver dentro
do log do console. Instale isso dentro de uma
constante chamada interagir. Agora, em vez de diretamente, vou colocar a função externa. Podemos colocar em nossa
constante atualização e ainda podemos ver que temos acesso a essa função interna. Tudo o que estamos fazendo aqui é criar
uma variável que armazena uma referência a essa função
retornada. Essa variável agora pode
ser usada em outro lugar. Agora, o que temos é uma referência de função
independência da função externa original. Isso agora nos deixa
com uma pergunta-chave. Esta função interna que
armazenamos em uma constante, acesse essa variável
de fora. Bem, podemos descobrir executando essa função colocando os colchetes
logo após essa constante. Diga isso, lembre-se que ainda estamos tentando acessar
seu valor externo. Atualize e ainda vemos
nossos dois registros de console. Significa que sim, ainda podemos
acessar essas variáveis externas. Isso pode parecer muito estranho. Estamos acessando variáveis
que parecem
não fazer sentido com o que
já aprendemos sobre escopo. Tudo isso se relaciona com
algo chamado fechamentos. Uma função, assim como
nossa função interna aqui, também
lembraremos a quais
variáveis ela tem acesso. No nosso caso, é
esse valor externo. Isso é o que é chamado de fechamento. O fechamento está colocando uma cerca em torno de tudo o que
temos acesso. Lembre-se de todas essas variáveis onde quer que essa função possa
ser chamada no futuro. Isso pode ser útil agora
porque, em vez de precisar
criar um valor externo
como uma variável global, podemos restringir
esse acesso a dentro dessa função e ainda permitir qualquer interno aninhado
funções para usá-lo. Além disso, note que esse
termo de fechamentos
só pode acontecer dentro das funções. Isso ainda não está claro. Vamos dar uma olhada em outro exemplo usando a pontuação do jogador, que precisa ser atualizada. Vamos apenas comentar tudo
isso e na parte inferior. Crie uma nova variável. Vamos rolar para ser igual a 0. Em seguida, crie uma nova função
chamada pontuação de atualização. Então, aqui dentro, o que
faremos é reatribuir nossa pontuação com o valor
da pontuação atual mais 10. Registre isso no console. Na parte inferior, chame nossa
função. Vamos testar isso. Este deve ser um
valor de 10, já
que temos nossa pontuação original de 0. Em seguida, chamamos nossa função
que adiciona 10
à pontuação original e, em seguida,
imprime o novo valor. Além disso, se atualizarmos
isso várias vezes chamando nossa função
mais de uma vez, eles também deveriam funcionar também. Tudo bem,
funciona como queríamos,
mas a pontuação que
temos fora de uma função é classificada
como uma variável global. Também pode ser atualizado
de outras áreas. Em vez disso,
será melhor ter mais controle sobre
essa variável e apenas atualizá-la dentro
das funções criadas
para esse fim. Você pode pensar, vamos
mover essa variável para a função.
Podemos arrastar isso para baixo. Essa técnica cria
um escopo de função e sua variável não pode
ser acessada de fora. Isso resolve um dos nossos problemas, mas também cria outro. Vamos ver isso dentro
do navegador, atualizar. Recuperamos o valor de
10 vezes livres porque a variável redefine de volta para zero no início de
cada chamada de função. Além disso, se este fosse um jogo real, também
podemos querer acesso
à variável de pontuação
fora dessa função. Talvez faça algo como exibir na tela para o usuário. Para ajudar com isso, podemos
fazer uso de um fechamento para aninhar dentro de uma função para
atualizar a variável de pontuação. Temos o invólucro externo da
pontuação de atualização. Em seguida, podemos criar um novo
aninhado em uma função chamada aumento com nossa
variável de pontuação dentro e também o log do console que são a
função interna, assim como antes. Além disso, armazene essa função
em uma nova variável. A primeira, diremos const, nova pontuação é igual a
esse valor retornado. Ainda poderíamos
chamar essa função várias vezes se você quisesse. Mas desta vez
precisamos fazer referência a essa nova pontuação, então ela muda. Também deixando entre
os parênteses logo depois, então, na verdade,
executamos essa função. Então tente isso refrescando. Agora, isso aumentou
pelo valor de 10 cada vez que
chamamos nossa função. Isso agora resolve os
problemas que tínhamos antes com a função de pontuação de
atualização original. Antes de fazermos essas alterações, redefinimos a
variável de pontuação de volta para zero. Isso significava que, como
vimos antes, cada vez que chamamos essa função, o resultado sempre foi
o valor de 10 e não
estava adicionando isso a
cada uma das chamadas. Os fechamentos resolverão
isso lembrando a variável de pontuação na memória
cada vez que for chamada. Uma variável de pontuação também agora tem escopo
mais estreito, portanto, não podemos ser atualizados acidentalmente em
outro lugar como poderíamos se fosse
uma variável global. se ainda
não precisássemos acessar essa variável de pontuação de
fora dessa função. Podemos retornar um valor e armazená-lo dentro
de uma nova variável. O que significa que ainda podemos acessar
essa pontuação de dentro do fechamento e
exibi-la para o usuário final.
56. Um Pouco De Fundo: Esta nova seção vem com alguns chavões, tais como: callbacks, assíncronos,
síncronos e também alguns conceitos
que podem ser difíceis de
entender sem
saber um pouco de antecedentes sobre o
motivo pelo qual os usamos. Este vídeo
tentará explicar isso em termos
simples e o que
exatamente cada um faz. Começando com código síncrono. Cada linha de código é
um pouco como uma tarefa, e cada uma é
concluída em ordem. linha 1 será lida, aguarde que isso seja processado
e, em seguida, passará para a linha 2. Também esperaremos que
isso termine
antes de passar para
a terceira linha. Em um pequeno programa como esse, realmente não
importa porque as operações são
rápidas e fáceis de processar, e você não notaria nenhum tempo de
espera entre cada uma. Mas em casos extremos, se uma linha nunca terminar o
processamento ou demorar muito tempo
, ficaremos presos. No navegador, podemos ver
alguns exemplos simples disso, então vá para esta
nova seção que
é o número 10, JavaScript assíncrono. Em um pouco de seção de
fundo temos dois exemplos, mas agora vamos nos concentrar no exemplo
1 que não está
comentado e também o
HTML no topo. Temos o botão e
o cabeçalho de nível 3. Ignore a imagem
por enquanto, isso está relacionado ao segundo exemplo. Tudo o que fazemos aqui é pegar esses dois primeiros elementos. Consultamos seletor,
selecionamos nosso botão. Adicione um EventListener
que escutará o clique e essa função
acionará um alerta
e, logo depois,
pegaremos nosso título e definiremos o
conteúdo do InnerText efetivamente dado a nós dois estágios
para essa função. Alertas podem ser bons, por exemplo,
assim, porque
bloqueiam a execução do
código até fechá-lo. Agora, se abrirmos isso
dentro do navegador; copie o caminho para isso,
cole-o e atualize, veremos nosso botão que agora
ouvirá o clique. Vou clicar nisso,
veremos o pop-up que é a primeira
linha da nossa função
e, se clicarmos
neste botão, ele se fecha. A próxima linha da função
é então chamada, que definirá o InnerText
do cabeçalho, então temos uma ordem clara
de coisas em execução. Temos o alerta
e, depois que isso terminar, ele se move
para baixo para definir o texto. Com este exemplo,
cada linha não será executada na
anterior conforme concluída. É assim que o
código síncrono funciona. Um dos problemas aqui com o código
síncrono é que uma única linha de código pode impedir o resto do
programa seja executado, e isso pode ser evitado
usando código assíncrono. O código ainda é lido
em ordem linha por linha,
no entanto, uma operação
não precisa ser concluída antes de passar
para a próxima linha. Efetivamente, todo o código é executado e, em seguida, é acionado um por um. Precisamos lidar com o que
fazer quando cada tarefa for concluída e essa é
a parte chave aqui
e, em seguida, no que fazer
se o código retornar um sucesso ou se
houver um erro. Olhando para o nosso segundo exemplo, vamos apenas
descomentar esta seção. Aqui temos algo
chamado fetch. Esta é a API Fetch, e lembre-se de
antes que temos certas APIs da Web, como o Canvas. Essa API Fetch
nos permite buscar coisas em uma rede que
poderia ser outro site, um banco de dados, um servidor ou uma API externa
que outra pessoa
criou e o importante aqui está a
chamada fetch é assíncrona. Ele será executado e, em seguida, permitirá que o restante do
código abaixo seja executado também antes que ele seja concluído
ou recupere os dados. A ideia principal aqui é que
obtemos dados de
outro lugar do que dentro
de nosso próprio aplicativo. Este exemplo seleciona
uma imagem da Wikipédia e, em seguida, armazena o valor de retorno
em uma variável. Vamos começar registrando o valor de retorno dessa
variável no console. Basta descomentar
este primeiro exemplo
e, em seguida, colocar em um log de console com o valor da variável que é ImageSource
do navegador. Entre no console e
veremos algo chamado Promessa. Recebemos de volta uma
Promessa e ela tem o resultado
entre parênteses pendentes, então o que você acha que
isso poderia ser tudo? Bem, vamos procurar
Promessas com mais detalhes em breve, mas remonta
ao ponto importante que mencionei antes. Ao usar
código assíncrono ou assíncrono para abreviar, precisamos lidar com o que acontece
se o código retornar um sucesso ou se
houve um erro,
e uma Promessa pode
lidar com isso para nós. Quando pedimos pela primeira vez
esta imagem da Wikimedia, não
sabemos neste momento se o site da Wikimedia está inativo, lento ou se há um problema de conexão entre
nós e seu servidor. Este registro do console abaixo foi imediatamente chamado
após nossa busca, então ele foi executado antes mesmo da
imagem voltar. É por isso que obtemos o
resultado de pendentes porque nunca
tivemos uma imagem para
realmente registrar no console. Como outro exemplo, se isso estiver pendente e não
tivermos uma imagem, se tentarmos
atrasar o log
do console três segundos? Bem,
vamos cortar isso. Podemos colocar em um tempo limite
que acionará uma função, e digamos três segundos. Dentro da função, coloque outro log do console antes, atualize e você pode ver
depois de três segundos, nossa promessa agora está cumprida. Temos uma resposta, então esperar três segundos,
isso
nos dá tempo para recuperar as informações ou a
imagem de que precisamos. Em vez disso, se esse fosse um código
síncrono, o restante do
código precisaria
aguardar o restante do
código precisaria
aguardar essa imagem
para voltar por três segundos, mesmo
que não precisássemos usá-la. Ou, alternativamente, se
nunca lidarmos com isso assim, a linha que imediatamente
segue nossa chamada de busca pode
tentar acessar nossa imagem que
você não tem de volta
e, portanto, causar um erro. Com isso em mente, analisaremos as promessas e outras formas de
lidar com uma resposta
nos próximos vídeos.
57. Funções de retorno de chamada: Este vídeo apresentará algo chamado função de
retorno de chamada. Um retorno de chamada é apenas
o nome dado a uma função que é chamada
depois que algo aconteceu. A anomalia usada
como um próximo
passo a ser dado quando algo for
concluído. Pelo que abordamos
anteriormente, sabemos que o código assíncrono pode
levar algum tempo para ser concluído. Isso pode ser obter
dados de um banco ou até mesmo salvar em um
banco de dados como exemplo. Vamos ver como isso
pode afetar nosso código. O código neste
exemplo começa com uma lista vazia e não ordenada. Agora, nosso script tem
uma matriz de usuários vazia. Um aplicativo típico que tem usuários provavelmente
teria
uma função para fazer uma chamada para nosso banco de dados e atualizar o
array desse usuário com o resultado. Temos uma função para simular isso e adicionar dois novos usuários. Tudo o que estamos fazendo dentro
dessa função é acessar nosso array de usuários e
colocá-lo em objetos de usuário. Então, quando tivermos nossos usuários de
volta do nosso banco de dados, que assimilamos aqui,
o que provavelmente vamos
querer fazer em seguida é criar uma nova
função que pegue todos os nossos usuários loops sobre cada um e, em seguida, ele
os exibe no navegador. Vamos dar uma
olhada em como fazer isso. Vamos criar uma função,
digamos ListUsers. Em ListUsers é primeiro
acessar uma matriz de usuários, vamos fazer um loop com forEach, que executará uma
função para cada um dos
nossos valores de matriz ou transmitindo
o nome da variável do usuário. Em seguida, execute isso antes de termos
essa lista vazia não ordenada, podemos criar um novo item de lista
para cada um de nossos usuários. Os elementos Const são iguais a
Document.createElement, crie um novo item de lista
e, em seguida, adicione o conteúdo do
texto dentro, que é o nome de usuário. Documents.createTextNode
onde podemos fazer uso de nossa
variável de usuário e acessar
a propriedade name. Como sempre, precisamos criar
nosso processo de três partes, que é criar os elementos, criar o conteúdo
e, na terceira parte,
é mesclá-los juntos. Para capturar os elementos pai, chamamos appendChild, adicionamos o nome
e, finalmente, adicionamos esse elemento à
nossa lista não ordenada. Primeiro pegue nossa lista não ordenada com Document.querySelector, adicione-a em nossa lista não ordenada e depois AppendChild,
que são nossos elementos. É isso para a nossa função
de usuário da lista. Podemos chamar isso abaixo e verificar se tudo funciona no navegador até mesmo os nomes dos nossos
dois valores de matriz. Isso funciona completamente bem.
Não temos problemas com dados
funcionais porque
sabemos que estão nesse mesmo arquivo. Mas, realisticamente,
o que provavelmente faremos é
recuperar nossos usuários de um banco de dados, e essa chamada de banco de dados seria assíncrona e
pode levar algum tempo. Se tudo isso correu bem, o tempo de atraso será pequeno, mas ainda assim um atraso. Para simular esse atraso, também
podemos adicionar um setTimeout
à nossa função de ambas. Vou pegar nossos usuários,
vamos cortar isso, colocar em uma
chamada setTimeout e, em seguida, uma função. Eu apenas adicionaria um
segundo atraso a isso. Abra o corpo da função
e cole em nossa matriz de usuários, e agora vamos ver o que
acontece dentro do navegador. Atualize e, mesmo
depois de um segundo, não
vemos nossos usuários
dentro do navegador. Agora, o usuário foi listado desde que estamos
imediatamente Lupin
dos usuários na parte inferior porque nossa função está
sendo chamada imediatamente. Isso está
acontecendo efetivamente antes do atraso
de um segundo do nosso tempo limite, o que significa que quando
tentamos acessar nossos usuários, ele não tem nenhum valor. Isso é uma coisa comum
para se ter que lidar, ao trabalhar com dados
armazenados externamente, basicamente
pedimos
os dados que precisamos, mas também precisamos garantir que
os dados sejam retornados e disponíveis antes que
possamos acessá-lo com segurança. Ele precisa estar em ordem para
que as coisas não quebrem. Mesmo que estejamos chamando as funções
na ordem correta, por isso somos criados nossos usuários e, em seguida, estamos
listando nossos usuários, o tempo de atraso está
causando o problema. Também podemos confirmar isso
com alguns registros do console. Primeiro de tudo, se colocarmos em um logo após onde
criamos nossos usuários, coloque no primeiro e
diremos que esta é a função
GetUsersFromDatabase
e, em seguida, também colocarmos
um dentro de nossa função de usuário de lista com
o texto dos usuários da lista. Se não tivéssemos
esse atraso de tempo rodando de
cima para baixo, você esperaria ver
o primeiro log do console, seguido por este aqui. Mas se salvarmos e atualizarmos,
o oposto acontece, vemos a lista de usuários fria antes do
GetUsersFromDatabase, e sabemos que esse
é o
caminho errado para o que precisamos fazer. Seria bom se essa função de usuário da
lista fosse
chamada apenas uma vez que o código em um tempo limite fosse considerado
um sucesso, e podemos fazer isso
introduzindo uma função de retorno de chamada. Para fazer isso, moveríamos a
lista usa chamada de função, retirá-lo e, em
seguida, passar a função de retorno de chamada para
GetUsersFromDatabase. Essa função de retorno de chamada
será então tomada como um parâmetro de
criar nossa função. Como qualquer outro parâmetro, esse nome está em direção. Não precisa ser callback, vamos colocar isso nele apenas para que fique claro o que estamos fazendo. Agora, podemos chamar essa função de
retorno de chamada
no final de setTimeout. Logo após o
registro do console, chamaremos isso como uma função e, em seguida, poderemos
voltar ao console e ver em
qual ordem eles aparecem. Atualize e recebemos um
erro dentro daqui. Dizemos que callback
não é uma função. Retorno de chamada. Isso só precisa não ter as
chamadas de função, pois estamos apenas passando uma referência a essa
função. Agora, atualize. As coisas parecem estar sendo executadas
na ordem correta. Recebemos nossos usuários
do banco de dados e, em seguida,
listamos agora os usuários
também podem vê-los restabelecidos de
volta no navegador. Essa solução é callback
assíncrono. Lembre-se, a partir do
último vídeo que síncrono se refere
ao código que é executado em ordem e uma operação precisa ser concluída antes de
passar para a próxima. Usando este exemplo
que acabamos de fazer, uma vez que os usuários tenham
voltado com sucesso do banco de dados, que simulamos
com nosso setTimeout, podemos usar nossa função coal back
the list users, e desta forma se as coisas forem
mantidas na ordem correta. Também podemos passar argumentos
adicionais para essa função também. Digamos que quiséssemos obter apenas os usuários que tinham
o papel de administrador, podemos passar isso,
exceto o parâmetro. Agora, quando chamamos nossa função de passar o papel de administrador, então isso é completamente bom. Podemos passar tantos argumentos quanto um, dois para a função. Devemos garantir que o
retorno de chamada seja sempre o último. Esse método de passar
funções como parâmetros de
função não
é novidade. Podemos ver isso se
voltarmos para um arquivo anterior. Vamos abrir a barra lateral, pular para a anterior e dentro do primeiro exemplo que adicionamos um ouvinte de
eventos. Primeiro ouvimos clicar e depois como o último parâmetro
que acionou uma função. Aqui nós o passamos em uma
função de retorno de chamada que
queremos executar uma vez que algo
tenha sido clicado, e também consideramos um método de
array que analisamos
algo como para cada um, que temos em este exemplo
atual. Cada elemento dentro
da nossa matriz, então
executamos uma função dentro da
qual também é um retorno de chamada, o que significa que essa técnica não
é novidade. Quando falamos de retornos de chamada, esses geralmente são uma
maneira tradicional mais antiga de fazer as coisas. Vamos ver formas mais
modernas a seguir. Mas os retornos de chamada são realmente
importantes para estar ciente, já que ainda há
muitos deles por aí e ainda estão em uso hoje. retornos de chamada também ficam um pouco de ódio
no mundo do JavaScript e não
porque eles não funcionam. É mais porque como as coisas
podem ficar confusas facilmente. Este exemplo que
acabamos de usar não é muito ruim. Porque tudo o que temos
é uma única função, que então chama de volta
uma segunda função. Mas o problema está
quando temos um retorno de chamada, que chama outra função de
retorno de chamada,
que chama outra função de retorno
de chamada, e assim por diante. Mesmo olhando para este exemplo, a função lista de usuários
também pode precisar de seu próprio retorno de chamada também. Então esse callback também pode precisar seu próprio retorno de chamada e, em seguida,
estamos presos em uma cadeia longa. Podemos comparar essa coisa
com nossas próprias vidas também. Temos uma ordem de tarefas que você deseja concluir
em uma determinada ordem. Digamos que queremos dirigir o carro. Mas antes que possamos
realmente dirigir o carro, precisamos caminhar até o carro, antes de caminhar até o carro, temos que encontrar as chaves, antes disso, temos que nos vestir e assim por diante. Esta é uma série de
tarefas que dependem da anterior a
ser concluída pela primeira vez. Isso é comparável às funções de
retorno de
chamada que estão sendo chamadas quando o
código anterior for bem-sucedido. São esses múltiplos callbacks que podem resultar
em uma grande bagunça. Para ver um exemplo disso, criamos algumas pequenas funções de
demonstração. Vamos comentar
tudo de cima. Agora, crie algumas novas funções. O primeiro é GetOutOfbed, colocado no console.log diz fora da cama, e depois duplique isso mais
três vezes, dando-nos quatro funções. O segundo é encontrar nossas
chaves e apenas console.log. O próximo é caminhar até o carro, e o último é
dirigir o carro. Vai dizer sim, já que
nossa tarefa está completa. Usando o que sabemos de nossa
demonstração anterior de callback, cada uma dessas
funções precisa ser passada para a próxima
função como retorno de chamada. Em seguida, chame isso dentro
de cada função. O primeiro GetOutOfbed. Isso vai
levar um retorno de chamada, que será executado
na parte inferior, passa para o segundo
também, chame nossa função. Não precisamos adicionar isso à nossa última função, pois ela não chamará
outras funções, já que esse é o nosso resultado final. Na verdade, desencadeou
essa cadeia de chamadas de todas essas funções, vamos criar mais
uma função para chamar todas essas funções. Crie uma nova função
chamada CompleteTasks. Podemos chamar essa função,
que é CompleteTask passando na primeira função que você deseja chamar de volta. Nosso primeiro em nosso
pedido é GetOutOfbed. O que vamos fazer agora
pode parecer bastante complexo, mas é basicamente a
mesma configuração de antes. Nós obteríamos usuários do banco de dados. Só que desta vez há
mais de uma função na cadeia, que
chamaremos de volta
e, em seguida, dentro da função
CompleteTask, podemos aninhar cada uma de nossas funções para chamar de dentro. O primeiro é sair da cama. Passe em uma função. Vamos até
o console
e ver o que acontece. Se atualizarmos, veremos
o texto de fora da cama dentro do console e,
se dermos uma olhada, este é o
registro do console no topo. A próxima festa será fundamental para entender
tudo isso. O que faremos
aqui é que estamos criando nossa primeira função
chamada CompleteTask. Isso é então chamado
em nosso primeiro passo, que é sair da cama, depois
passamos uma função para dentro. Essa função é aceita
como retorno de chamada, e essa função é chamada no final
dessa função. Basicamente, uma vez que esta
função tenha terminado, ela chamará
nossa segunda função, que está aninhada dentro. Esta próxima seção, que
vamos chamar, pode ser nossa próxima etapa,
que é findkeys. Vamos chamar essa função, findkeys também precisa tomar
uma função de retorno , então passe isso. Isso agora deve executar nosso
segundo console.log. Tenho um erro de ortografia, então vamos mudar
isso, findkeys. Agora temos nosso
segundo console.log, então será executado nesta seção
aqui e, em seguida, ele executará
esta próxima função é que a próxima
função está aninhada dentro. Passando nossa próxima etapa, que é caminhar até o carro. Caminhe até o carro também recebe
uma função de retorno de chamada. Vamos salvar e atualizar, enviar impressões o
texto da caminhada. Em seguida, ele executará nossa próxima
função, que está dentro. O estágio final, é
dirigir o carro. Este é o último estágio, por isso não leva
uma função de retorno de chamada. Podemos simplesmente chamar isso
como uma função regular. Atualizar. Este código é executado ao lado de todas as
nossas outras funções. Se você quiser, também podemos
passar etapas adicionais ou código
adicional para cada
uma dessas funções também. Só para esclarecer, tudo o que
estamos fazendo aqui é criar uma
função principal que é executada, e então sua função é chamar
funções adicionais dentro. Cada uma dessas funções, esperaremos que o
código seja concluído antes
de chamar de
volta para a próxima. Se isso está começando
a parecer um pouco confuso, bem, provavelmente é, porque está uma
bagunça, e é por isso que algumas formas alternativas de lidar com isso
estão sendo criadas. Mas só porque
há novas maneiras, isso não significa necessariamente que
isso ainda não seja relevante. retornos de chamada ainda
são uma parte importante do JavaScript, tanto no momento, e
você também verá isso em código legado também. Você provavelmente
ouvirá esse tipo de coisa também chamada de retorno de chamada ****,
a Pirâmide da Perdição, retornos de chamada
aninhados. Também muitos outros nomes também. Todos esses nomes apontam para a mesma complexidade de
callbacks aninhados assim. Nos próximos vídeos,
você descobrirá algumas formas alternativas
de lidar com isso, incluindo o uso de retornos de chamada de
forma assíncrona com promessas.
58. Prometes: Sabemos agora que fazer uma solicitação
assíncrona
pode levar algum tempo, talvez apenas alguns milissegundos, ou talvez alguns segundos, minutos ou nunca
mesmo completo. Muitas vezes, quando estamos falando
sobre essa coisa, ela se refere a buscar
algo de outro lugar, como um servidor, algum tipo de armazenamento de dados, uma API ou um site externo. Uma promessa é ótima para
lidar com esse resultado. Promise é um objeto
e esse objeto representa o resultado
de uma tarefa assíncrona. O resultado pode ser uma falha, talvez não
voltemos do
servidor o que pedimos, ou pode levar um pouco de tempo. As promessas se apegam a essa tarefa e prometem dizer-lhe
no futuro quando ela
souber o resultado. Já vimos promessas e alguns dos resultados já. Alguns vídeos atrás,
olhamos para um exemplo simples de buscar uma imagem
da Wikimedia. Vou usar a API Fetch. Fetch é uma operação assíncrona, e estamos vendo uma promessa
retornada no console. Quando tentamos
acessar a promessa muito cedo antes de ela terminar de
pegar a imagem, os resultados foram
vistos como pendentes. Em seguida, adicionamos um pequeno
atraso de tempo com um tempo limite definido, que foi alterado na
promessa que estava sendo cumprida. Esses são dois
dos três
estados disponíveis com promessas. Pendente é o estado
inicial quando ainda
não sabemos se a tarefa
será concluída ou não, depois cumprida quando a
tarefa foi considerada um sucesso, como quando os dados
voltaram e agora estão prontos para uso. Também temos um estado chamado rejeitado quando a
tarefa falhou. Não temos os
dados que solicitamos e precisamos fazer
algo a respeito. Você também pode ouvir a palavra
resolvida com promessas. Estabelecida é quando conhecemos
o destino da tarefa, que
significa que ela é
cumprida ou rejeitada. Não precisamos
saber nada sobre o estado pendente, pois não podemos dizer em que direção ele
seguirá com o resultado. Mas precisamos lidar com
um sucesso ou um fracasso. Para os arquivos iniciais, que é a seção de promessas. Aqui, temos outro exemplo
usando essa API Fetch. Isso está buscando dados
de uma API externa, e isso é apenas
um URL externo. Este URL
selecionará uma imagem de cachorro aleatória. Podemos copiar isso e colar
isso dentro do navegador. Podemos ver que temos um resultado
em um formato chamado JSON, que significa JavaScript
Object Notation. É uma sintaxe para trocar
dados pela Web. Parece um objeto
JavaScript, mas na verdade é independente da
linguagem, o que significa que também pode ser criado e passado por outros idiomas. Podemos ver que temos uma mensagem, que contém um URL para
uma imagem de cachorro específica e o código de sucesso. Podemos copiar essa imagem
e colar este link, o que nos dá acesso
à imagem específica. Eu instalei a extensão
do navegador para fazer com que isso pareça um
pouco mais bonito. seu pode parecer um
pouco mais difícil de ler, mas os dados
ainda devem ser exatamente os mesmos. Volte para o editor. Como sabemos, a
chamada de busca é assíncrona, então podemos lidar com o resultado de buscar essa imagem
com a promessa. Primeiro, podemos lidar com
o estado cumprido, que é um sucesso, e fazemos isso
encadeando no final da chamada de busca. Podemos remover o ponto e vírgula, encadear para o fim.então. Então é um método que
podemos encadear em uma promessa. Lembre-se, quando
usamos a API Fetch, isso retornará uma
promessa como resposta, o significa que temos acesso
ao método then. Passe em uma função. Com isso sendo um retorno de chamada
assíncrono, só
executaremos o
código dentro daqui. Quer saber que a tarefa foi
concluída com sucesso. Claro, provavelmente
queremos acessar os dados que recebemos
de volta da chamada de busca. Isso pode ser passado
para nossa função,
portanto, passar
nomes de variáveis, como resposta. Em seguida, poderíamos registrar isso no console e verificar se isso funciona. Vou salvar no navegador e abrir o console.
Há uma resposta. Essa promessa bem-sucedida retorna
um objeto de resposta que contém detalhes do que recebemos de
volta do servidor
ou da API. Esse objeto contém coisas
como o código de status. No nosso caso, são 200, o que significa que está tudo bem. Até o URL baixo, vemos o URL real que
solicitamos
na chamada de busca em vez
do URL da imagem
que recebemos de volta. A razão pela qual não vemos isso é porque todos os dados que recebemos de volta são armazenados
nesta seção do corpo. Se
abrirmos isso, ainda não
veremos o URL da imagem real. Em vez disso, vemos um fluxo
legível. Isso remonta ao
formato JSON mencionado anteriormente. Para ler este formato JSON que está armazenado na seção corpo, temos um método JSON
que podemos usar. Dentro do log do console, podemos adicionar no
final o método JSON. Então vamos tentar este
. Salve e atualize. Estamos de volta a uma promessa que tem o
estado atual de pendente, significa que a tarefa ainda
não foi concluída. Isso ocorre porque o método
JSON também retorna uma promessa que
precisamos lidar novamente. Há algumas
maneiras de fazer isso. Primeiro, podemos remover
o invólucro de log do console e deixar response.json. Como esse método JSON também
retorna uma promessa, também
podemos encadear
o método then. Passe isso, que novamente
ele executa uma função. Além disso, essa função, ele recebe os dados da resposta, então passa para uma variável de dados. Em seguida, podemos registrar esses
dados no console. Vamos tentar isso,
salvar e atualizar. Agora,
passamos com sucesso nosso conteúdo JSON, que é armazenado
na seção de corpo. Isso retorna a imagem
real do cão, que é armazenada na mensagem,
e também o sucesso como
o código de status. Essa é a mesma resposta
que vimos quando
colamos isso no
navegador mais cedo. Tudo aqui
retorna uma promessa, a chamada de busca
retorna uma promessa e também o JSON
retorna uma promessa. Mas outra maneira de fazer isso, que eu pessoalmente prefiro, mas depende completamente de você, é não aninhado, então,
chamadas assim. Se possível, minha preferência
é mantê-los todos no nível superior
para legibilidade. Para fazer isso, precisamos
cortar o método
aninhado que
acabamos de adicionar. Vamos deixá-lo em
response.json dentro daqui, e vamos cortar o
segundo para o último conjunto de colchetes até
logo após a response.json. Corte isso. Agora, a função deve
sair com response.json. Certifique-se de que o ponto e vírgula
seja removido do final, e podemos colar
isso no final, dando-nos dois
métodos seguidos. No entanto,
se passarmos para
o navegador e
atualizarmos, veremos a mensagem de indefinida. Isso ocorre porque
estamos tentando acessar os dados do nosso método
anterior. Mas primeiro, para fazer isso, precisamos devolver isso. Tudo isso funciona da mesma forma que antes. Também podemos encadear
tantos desses métodos como 1, 2, e cada um
aguardará o resultado anterior terminar antes de executar
o código dentro. Manteremos controle total sobre nossa tarefa assíncrona e sobre a ordem
em que o código é executado. Também podemos filtrar isso
como qualquer outro objeto. Poderíamos acessar a mensagem, que é a URL da
imagem que você precisa. Podemos clicar nisso e abrir
isso dentro do navegador. Também podemos usar esse URL
de imagem e passá-lo para um elemento de imagem. Primeiro, adicione um elemento de
imagem vazio logo acima do nosso script
e, em seguida, no segundo
método, quando soubermos que temos acesso a esse URL, podemos remover este log do console, selecionar nossa imagem elementos
com o seletor document.query e, em seguida, defina o atributo
source como igual a data.message. Vamos salvar isso e
atualizar o navegador. Cada vez que atualizarmos, obteremos imagens aleatórias
diferentes de
volta da nossa API. Este é o
estado atendido tratado. Mas e se
houver um problema e
recuperarmos um estado rejeitado? Isso acontecerá se houver
um erro ao buscar os dados ou concluir a tarefa
que solicitamos. Isso nós encadeamos no
final um método catch. Aqui, estamos encadeando
o método do evento , removemos o ponto e vírgula
e, em seguida, encadeamos
no final do método catch que
executaremos se houver um erro, passamos esse erro para
esta função de retorno de chamada. Muita função com o erro com
base em um log de console. Vamos começar com uma seqüência
de que houve um erro. Também podemos adicionar ao
final a mensagem de erro também. Se testarmos isso e
atualizarmos, não
veremos nada dentro do console porque a imagem está sendo
retornada com sucesso. Para realmente testar isso,
precisamos entrar nas ferramentas
do desenvolvedor e
entrar na guia rede. Selecionarei isso
e, para fazer isso, podemos realmente
desligar nossa rede. Vamos fazer isso um
pouco maior. O Chrome tem esse menu suspenso
que você pode ver aqui. Atualmente, não
usamos nenhuma limitação, mas também podemos alternar isso para uma conexão lenta
ou mesmo offline. Se fizermos isso e entrarmos
no console e atualizarmos, desligar essa
rede significa quando agora não obtemos a
imagem que queremos. A promessa
agora deve lançar um erro. Com tudo isso, a última
coisa que vamos ver é o método
finalmente. O método finalmente será executado
independentemente de a promessa sido cumprida ou se
ela foi rejeitada. Isso também pode ser
acorrentado no final também. Como em todos os métodos acima, também
precisamos
remover o ponto e vírgula como no método finalmente, que novamente ele executa
uma função de retorno de chamada. Coloque em um registro de console com o texto de,
eu sempre vou executar. Com a rede
ainda desligada, podemos atualizar e
ver essa mensagem. Vamos ligar a rede novamente,
atualizar, pular para o console e ainda vemos
esse registro do console mesmo quando a promessa
foi um sucesso. O método finalmente é
útil para acompanhar algum código que precisamos
executar após a conclusão da
promessa. Alternativa seria
colocar esse código em ambas as seções então também
captura. Mas isso resultaria
em código duplicado. Isso é promessas e
como pode ser realmente útil com JavaScript assíncrono. Tudo isso é possível
porque o método fetch retorna
inicialmente uma promessa
de iniciar toda essa cadeia. Mas e as coisas que
não retornam uma promessa? Bem, em seguida, vamos dar uma
olhada em como podemos lidar com isso.
59. O Construtor Promessa: No exemplo anterior, poderíamos começar a
usar promessas porque a API Fetch retorna uma promessa. Mas e as funções
que não retornam uma promessa? Para iniciar as coisas, vamos escrever uma função
personalizada simples, e isso será executado e definirá alguns dados após um tempo limite. Vou entrar no arquivo do construtor de
promessa, que está atualmente vazio
dentro do script para criar uma variável
na parte superior chamada data. Defina isso para um objeto vazio. Crie uma função chamada GetData. Em seguida, passe
dentro do nosso setTimeout, que vai
assumir uma função. Como uma função Então,
logo depois disso, vamos executá-lo após 2.000
milissegundos de tempo de atraso. Depois de dois segundos, tudo
o que queremos lidar com essa função é definir nosso objeto de dados
para ter um valor. Vamos reatribuir isso para ser um novo objeto onde passaremos uma propriedade name
igual a uma string. Isso chamará GetData para
realmente executar nossa função. Então, no final,
registraremos o valor dos dados, podemos ver o que recebemos de volta. Analisando nossos dados. Também podemos ir para o nome também. No navegador, abra o arquivo e
pule para o console. O console vê o
valor de indefinido. Isso provavelmente não é surpreendente
porque acessamos o objeto de dados dentro do log do console antes
mesmo de definirmos a propriedade name, os dados levam dois
segundos para serem definidos. Esta é uma
solicitação um pouco simulada para um banco de dados, livre para lidar com o que
acontece entre solicitar os dados
e recuperá-los. Nenhuma promessa é boa para isso, mas essa função não
retorna uma promessa por padrão. Para isso, podemos criar o nosso próprio usando o construtor de
promessa. Construtores é algo
que já
vimos com o novo
operador no passado. Nós olhamos para coisas
como novas matrizes. Analisamos o novo objeto
e também a nova função. Tudo isso cria uma nova
instância de um objeto. Lembre-se de que as promessas também
são objetos. Também podemos usar esse novo operador para criar
uma nova promessa nós mesmos. Primeiro comente
nosso exemplo por enquanto, que é tudo, exceto a variável de dados. Remova isso. Então podemos começar a construir
nossa nova promessa abaixo. Apenas com os exemplos que
vimos antes, usaremos a nova palavra-chave
para criar uma nova promessa e esse construtor assume uma nova função que
será executada. Esta função usa
dois parâmetros opcionais, uma função a ser executada se a
promessa for resolvida em um, se a promessa tiver
sido rejeitada. Esses são nomes de nossa escolha, mas resolver e rejeitar
são bastante descritivos. Qual é a nossa
própria promessa personalizada, definimos exatamente quando
e onde queremos que essas
funções de resolução e rejeição sejam executadas. O primeiro passo é
armazenar nossa promessa
dentro de uma variável. Vamos chamar essa promessa. Posso chamar isso
em apenas um momento. Mas vou simplesmente chamar
a resolução para resolver essa promessa. Então, depois,
podemos fazer uso
dessa variável de promessa
que está abaixo do frio, depois pegar e finalmente métodos que
analisamos anteriormente. Podemos acessar a promessa. Então, e esse método é exatamente o
mesmo que vimos
no vídeo anterior, que leva em uma função
que vai ser executada, o código foi um sucesso. Com isso em mente,
colocaremos em um registro de console com
o texto de sucesso. Permita isso e certifique-se de que nenhum
ponto e vírgula esteja no final. Também vamos entrar no final
da promessa. O método catch, que
também assumirá uma função. Lembre-se de que o método catch também
passará o erro, que podemos colocar
dentro de um log de console. Vamos até
o console agora e ver qual deles
foi registrado. Vemos o valor do sucesso, que não é surpreendente porque resolvemos essa promessa, o que significa que ela foi bem-sucedida. Essa função de resultado também pode ter um valor de atendimento
que você deseja transmitir. Digamos que uma série de sucesso. Então essa
mensagem de sucesso também será transmitida pela cadeia se
isso tiver sido bem-sucedido. A seção bem-sucedida
é a seção then. Podemos passar isso
para nossa função. Podemos armazenar isso dentro de
uma variável, como resposta e, em seguida, podemos
registrar isso no console. Atualize, e lá vamos nós. Isso é útil se você precisar
passar alguns dados personalizados ou mensagens para a seção de
resultados. Mas voltando ao exemplo
anterior de buscar alguns dados
que tínhamos acima, esse seria um exemplo melhor do que simplesmente
enviar uma mensagem. O que vamos fazer
é copiar e colar esta seção de tempo limite de
dentro da função. Em seguida, podemos colar
isso logo acima da seção de resultados e
descomentar todas as três linhas. Em seguida, podemos mover
a seção de resultados para estar dentro do tempo limite. Ele também definirá os dados e resolverá
essa promessa. Isso significa que a
promessa agora só deve ser resolvida após a definição
dos dados. Podemos testar isso fazendo
login no console. Entre na seção then, se isso tiver sido
bem-sucedido com um novo console registre o
valor de nossos dados. Atualizar. Dê dois segundos. Veja a mensagem de sucesso e nosso objeto foi
atualizado com nossa string. É assim que podemos lidar com
um sucesso com uma promessa. Mas e quanto a rejeitar? Bem, já que essa é a nossa promessa, podemos fazê-lo fazer
o que quisermos. Este exemplo, que tal resolver
com sucesso é que o
nome de Chris foi definido. Estou rejeitando se o objeto de
dados estiver vazio. Podemos entrar em nosso tempo limite logo abaixo, onde
definimos nossos dados. Podemos colocar uma declaração if. Podemos verificar se o Object.keys
tem em nosso objeto de dados. Podemos verificar se o comprimento
disso é maior que zero. O nome sendo a propriedade
key aqui, estamos verificando se o comprimento
desse objeto é
maior que zero. Se for, isso
significa que isso foi definido onde podemos passar
na função de resolução. Uma mensagem de sucesso. Caso contrário, logo após a
instrução if passará em rejeição, que terá passado
para nossa função com a mensagem de rejeitado. Vamos tentar isso. Teremos conjuntos
de propriedades de dados, então devemos esperar o valor do sucesso. Dá isso dois segundos. Isso tem sido um sucesso. Se quisermos verificar
o estado rejeitado, podemos verificar se Object.keys
é igual ao comprimento de zero, que resulta em uma promessa
rejeitada. Há um pouco acontecendo aqui, mas a ideia é bem simples. Se uma função por padrão não retornar uma promessa,
podemos criar a nossa própria. Isso pode resolver ou rejeitar a qualquer momento que achamos que deveria, dando-nos controle total
do comportamento de nossa função.
60. Tratar múltiplas promessas: Quando entendermos
como as promessas funcionam, lidar com uma AsyncTask
se torna muito mais fácil. Mas e se tivermos
mais de uma AsyncTask em
execução ao mesmo tempo, isso pode causar vários problemas. Esperamos que a primeira tarefa seja concluída antes de
passar para a próxima? Como exemplo, se tivéssemos 10 AsyncTask
em execução ao mesmo tempo, se esperássemos por cada uma terminando antes de passar para a próxima, o atraso de cada um
poderia realmente somar. Além disso, como exemplo, se a tarefa número 10
dependesse do valor da tarefa número 3, mas a tarefa 10 terminasse primeiro. Bem, para ajudar com alguns
desses problemas, temos acesso a alguns métodos de promessa
úteis. Nós cobrimos alguns
métodos até agora, incluindo então,
catch e, finalmente, e esses próximos
métodos vão lidar com várias promessas, começando com um
método chamado ALL. O método ALL percorre
várias promessas e retorna uma única promessa e uma única promessa resulta
para uma matriz do resultado. É útil para coletar
vários
dados e talvez
agregá-los em um único resultado. Vamos dar uma olhada em como
isso funciona no iniciante. Tenha duas
promessas separadas armazenadas em variáveis. Promessa número 1. Este novamente é um exemplo simples
que vimos antes onde buscamos uma
imagem da nossa API. Se isso tiver sido bem-sucedido, ele executa uma função que retornará o
valor da resposta. Junto com isso,
teremos a promessa número 2, que está usando o construtor de
promessas que foi visto
no vídeo anterior. Isso será resolvido
após dois segundos. Eu os mantive deliberadamente
simples para este exemplo. Mas imagine que queríamos saber se ambos foram um sucesso. Em vez de ter que verificar
cada um individualmente, bem, para isso podemos
fazer uso de promessa.all. Na parte inferior, a promessa de acesso, maiúsculo P. O método ALL. Vamos passar em uma matriz contendo ambas as variáveis,
então prometa 1, promessa 2. Esse
método promise.all terá qualquer valor iterável
, como uma matriz. Nós olhamos para looping sobre arrays em abundância durante esta aula. Além disso, esse método ALL
retornará uma promessa também, o que significa que podemos encadear
no final vários métodos,
como then e catch. Faremos exatamente o mesmo
que fizemos anteriormente. Vamos encadear então, o que
assume uma função. Essa função também pode
receber os resultados. Vamos registrar isso no console. Depois, se
houve um erro, também
podemos encadear
in.catch no final como uma função ALL que recebe
o erro, coloque no log. Então vamos dar uma chance a isso. Para o navegador, verifique se
a página atual está aberta. Atualizar. Depois de dois
segundos, voltamos ,
retornamos e uma matriz
com dois resultados. A primeira é a
nossa imagem aleatória, que é armazenada
dentro desse objeto. Se abrirmos isso, podemos ver que este
foi um sucesso. O segundo, porém,
após o tempo limite, é mostrado como indefinido, já que a promessa não
retorna nada. Se quisermos, poderíamos passar um terceiro parâmetro para setTimeout. Vamos entrar e fazer
isso. Separe por vírgula. Vamos passar uma
string simples como resultado, que é um
parâmetro opcional para passar para
a função que estamos
chamando, que está resolvida. Agora, após uma atualização, veremos esse valor
dentro do console. Também podemos testar uma
falha e ver o que acontece se uma dessas
promessas for rejeitada. Podemos fazer isso ao invés de
resolver, podemos passar,
rejeitar e este fora e, em seguida, vou pegar a seção, o log do console será executado. Vemos esse valor de resultados
que passaremos aqui. Mas uma coisa que
você notará é que não vemos a imagem aleatória. Mesmo que estejamos
passando
essas duas promessas de prometer. Tudo, só
vemos o
resultado de rejeitado. Isso ocorre porque, ao
usar o método ALL, ele só será resolvido se todas as
promessas que ele faz nos resultados com sucesso
ou se uma única falhar. Ou estamos
recebendo com sucesso uma matriz contendo todas
as promessas como
vimos antes ou a
primeira que foi rejeitada. No entanto,
pode haver ocorrências quando esse não é o
comportamento que queremos. Podemos ainda querer que todas
as promessas sejam devolvidas, independentemente de
haver uma falha ou não. Para isso, podemos substituir
todos por todos resolvidos. Tudo resolvido ainda
vai assumir uma matriz contendo
todas as promessas. Mas agora, se salvarmos
isso e atualizarmos, dê dois segundos. Em vez de ver
a única falha, vemos todas as nossas promessas
dentro da matriz. O primeiro foi cumprido.
Veremos todo o valor. Então veremos o
segundo que foi rejeitado. Poderíamos usar esses resultados da
maneira que quiséssemos,
como fazer um loop sobre
eles para lidar com o que fazer se houvesse um
fracasso ou um sucesso. Por exemplo, talvez queiramos
saber quais
foram rejeitados para que
possamos chamá-los novamente. Ou até talvez apenas mostre a um usuário uma determinada seção se a solicitação
do usuário for um sucesso. Outra coisa
que temos são dois métodos chamados qualquer e raça. Ambos
retornarão apenas um valor. Primeiro, vamos dar uma
olhada em qualquer que possamos usar no lugar de todos os assentados. Salve e atualize e
veremos o que recebemos de volta. Desta vez, não
vemos a rejeição. Tudo o que vemos é nossa imagem
bem-sucedida. Isso ocorre porque qualquer
método, como parece, resolverá assim que qualquer uma das promessas passadas para
ele for cumprida. que basicamente significa
a primeira promessa, que é um sucesso. Isso nem sempre significa
que ele será
o primeiro que é
passado na matriz. Significa apenas o primeiro
que foi concluído. O método de corrida no entanto, se dermos uma olhada
nisso, Salvar e Atualizar, isso também retorna
a mesma imagem aleatória, mas isso retornará a
primeira promessa passada para ela, que foi resolvida. liquidado pode até ser
cumprido ou rejeitado. No nosso caso, é uma imagem aleatória porque esta volta mais rápido porque não
tem atraso de dois segundos. Independentemente de a
promessa sido um sucesso ou um fracasso, a primeira volta será a que você vê
no console. Para recapitular, o
método de corrida retorna a primeira promessa
que encontra , que resolve ou rejeita. O método qualquer também
retornará uma promessa, mas esta tem
que ser cumprida. Ambos são muito
úteis se
alguma dessas
situações surgir.
61. Async / Aguarde: Com a chegada do ES 2017, surgiu uma nova maneira de lidar com o código
assíncrono. Muitas vezes olhamos
anteriormente é redundante, tudo ainda é algo
que precisamos saber, especialmente para o que
vamos ver agora, que é algo
chamado async/await. Async/Await é realmente
promessas nos bastidores, mas foi criado
para parecer mais simples
e ser mais fácil de
ler para os desenvolvedores. Parece mais simples porque
voltamos a algo
mais familiar, que é uma função. Nos arquivos iniciais, teremos
um exemplo de imagem em que
retornaremos uma promessa que
vimos anteriormente. Se você usasse uma função regular
para definir essa imagem, faríamos algo assim. Isso provavelmente criará uma
função chamada set image
e, por dentro, poderíamos novamente fazer uso de
nossa chamada de busca. Cole isso e guarde isso dentro de uma constante
chamada resposta. Então, vamos tentar fazer um registro de
console para a resposta
e, como todos vocês sabem em vídeos
anteriores, aqui estamos tentando
acessar esse código assíncrono imediatamente logo abaixo antes que ele possa ter a
chance para voltar. Para executar isso, chame nossa função de imagem
definida, atualize o console,
voltamos ao estado pendente. Podemos ver a resposta,
que é nossa URL, que originalmente
chamamos dentro daqui,
em vez de nossa
imagem real, que recebemos de volta. O que você pode estar pensando
que poderíamos fazer em seguida é usar response.json.
Vamos experimentar isso. Armazene isso dentro de uma
constante chamada imagem, que é igual a response.json. Podemos passar essa resposta. Agora, olhe esta imagem, o console. Vamos
tentar isso novamente. Desta vez, recebemos um erro, dizendo que response.json não
é uma função, e isso acontece
porque os dados
da imagem ainda não estão disponíveis. Temos promessas que
sabemos que temos que
encadear no final
de todas as chamadas de busca, depois métodos, que aguardam
a resposta bem-sucedida
antes de executar uma função. No entanto, embora não estejamos
usando promessas desta vez, vamos usar async/await. Para isso, temos
duas etapas simples. Para converter nossa
função regular em uma função assíncrona, tudo o que precisamos fazer é passar a palavra-chave
assíncrona na frente dela. Depois de fazer isso com uma marca, qual linha de código
queremos aguardar nos dados que retornam antes de
passarmos para a próxima. Agora, caso queiramos
aguardar o retorno da imagem, e isso efetivamente
pausará nossa função e
aguardará os dados retornem antes que os dados retornem antes de
movê-los para o
resto do código. Vamos salvar isso e
ver o que acontece. Se agora atualizarmos, o
erro desapareceu. A promessa ainda é estados
independentes, mas se
abrirmos isso, poderemos acessar os dados que
precisamos dentro desse objeto. Agora podemos ver se copiamos
essa imagem com citações, agora
recuperamos nossa imagem
aleatória de cachorro e a mensagem de sucesso. A razão pela qual precisamos
mergulhar nessa promessa é porque estamos tentando acessar nossa response.json na
linha logo abaixo. Ainda esperamos que nossa
imagem volte, mas depois fizemos login
no console response.json. Mas lembre-se de exemplos
anteriores, o método json também
retornará uma promessa também. Para lidar com isso, tudo o que
precisamos fazer é aguardar nosso método json para finalmente terminar antes de registrarmos
isso no console. Agora, se salvarmos isso, tente isso novamente no navegador, vez de ter
que pular dentro da promessa e entrar no objeto. Agora, veja diretamente as informações
corretas que precisamos dentro do console. Agora retornamos o URL
dentro dessa propriedade message, que podemos usar para definir nossos elementos de imagem.
Vamos pegar isso. Podemos remover o console log access
document.queryselector. Não estava na imagem que podemos definir a fonte da
imagem como igual à image.message. Lá vamos nós. É assim que podemos usar async/await com esse estilo de função
regular. Mas também há
diferentes tipos de funções disponíveis
que você viu, incluindo expressões de função
e funções de seta. Assim mesmo. Com uma expressão de
função. Diga let func como o nome da variável e diga
isso igual à nossa função, que simplesmente
retornará uma string de hey. O equivalente à função de seta
ficaria assim. Aqui temos nossa expressão de
função e, em seguida, temos
nossa função de seta. Async/await pode ser usado
em qualquer um desses. A maneira de marcar nossa expressão de
função como assíncrona é
exatamente como acima, passando a palavra-chave assíncrona logo antes da palavra-chave
function, e também o mesmo para
nossa função de seta também. Podemos colocar isso logo
no início
e, em seguida, podemos usar
a palavra-chave await em qualquer lugar dentro
do corpo da função. Async/AWAit é uma solução limpa
e poderosa para lidar com tarefas assíncronas. Mas precisamos ter cuidado para
não nos empolgar demais. Neste exemplo, estamos definindo a imagem
na próxima linha. Faz todo o
sentido aguardar os dados voltando
antes de usá-los. Mas imagine se tivéssemos
algo assim. Se duplicarmos essa resposta e pedimos nossa
imagem separada. O que estamos fazendo aqui é
que estamos fazendo duas solicitações para duas imagens independentes ao
mesmo tempo. Mas o problema que temos
atualmente é que a segunda imagem
não será chamada até que a primeira
retorne porque
usamos a palavra-chave await. Agora isso causará
um atraso de
tempo desnecessário no código abaixo. Aqui, estamos tentando
acessar nossa primeira imagem, mas ainda precisamos esperar
que a segunda imagem seja
retornada antes mesmo dessa
linha ser executada. Usamos uma onda, mas
precisamos aguardar os dados, que precisamos e depois. Mas ainda não queremos
impedir que o resto
do código seja executado,
se não precisarmos. várias
solicitações como essa é algo que veremos
em seguida com mais detalhes. Além de procurar
logo o tratamento de erros também.
62. Manuseamento de Múltiplas Esperas: No final do vídeo
anterior, discutimos os efeitos
de várias chamadas aguardadas. Aqui, temos três,
temos resposta, responde 2 e resposta 3, que fazem a
mesma chamada de busca. Sabemos, por exemplo, que se
a segunda imagem precisasse
esperar que os dados da primeira imagem voltassem antes de serem executados, isso estava completamente bom. No entanto, se a imagem 2 não depender da primeira imagem, ela não deve bloquear esse
código desnecessariamente. Com várias
solicitações de dados assíncronos como esse, isso nos leva de volta a
um vídeo anterior, onde analisamos como
lidar com várias promessas. E se quisermos saber se alguém
falha ou se todos falharem, como iríamos lidar com
isso? Com promessas,
poderíamos usar métodos como todos e todos resolvidos. Mas com código assíncrono, essas promessas também estão
sob o capô. Ainda podemos fazer uso
desses métodos, como todos. Por exemplo, na
parte inferior dentro da nossa função, podemos acessar a promessa a todos, o que leva em uma matriz. Podemos passar em resposta, resposta 2 e também resposta 3. Vamos armazenar isso
dentro de uma variável ou constante chamada resultado
e, em seguida,
registrá-lo no console. Um erro, então isso
precisa de resposta. Isso ainda retorna uma promessa, mas lembre-se de que o método all será resolvido em uma única promessa, se todas as promessas realizadas forem resolvidas com sucesso ou se uma única falhar. Com isso em mente, também
podemos usar a palavra-chave await para garantir que todos
eles resolvam primeiro antes de
passar para a próxima linha. Passe aguardar,
é antes disso. Agora estamos aguardando todas
essas três promessas para completar agora. Isso significa que agora podemos remover
a palavra-chave await antes cada uma dessas chamadas
independentes gratuitas. Vamos experimentar isso, atualizar. Agora obtemos uma matriz com todas as
três respostas separadas. Podemos entrar em
cada um desses. Mas um dos problemas
que ainda temos é, se olharmos para o URL, esta é a
URL da imagem que estamos solicitando dentro de uma busca, não a imagem JPEG real, que está
voltando de a API. Se você se lembra, para acessar essa
imagem real que precisamos, isso está contido
dentro do corpo e para ler o
conteúdo do corpo, precisamos novamente fazer
uso do método JSON. O método JSON lerá
o conteúdo disso e transformará em um
objeto JavaScript que podemos ler. Como podemos ver, temos uma matriz com três valores separados. O que podemos fazer é que
poderíamos remover nosso log e
loop do console sobre todos esses três valores com o método
forEach, portanto, resulta. Para cada função, armazene
isso dentro do valor. Agora podemos registrar esse valor
no console e chamar o método JSON para cada
um desses valores. Isso agora nos dá de volta nossas
três promessas separadas. Mas se abrirmos isso, veremos um objeto familiar no
qual precisamos
mergulhar para recuperar nossa imagem
real. Isso acontece porque, como
vimos anteriormente, o método JSON
também retornará uma promessa. Para esperar que esses dados
voltem antes de acessarmos isso, podemos usar a palavra-chave await
e, como a palavra-chave await só
pode ser usada
dentro de uma função, podemos marcar isso como assíncrono. Recarregar. O que, em seguida, nos devolve nossas três
imagens, que precisamos. Esse método agora significa que
podemos fazer algo depois todas as promessas tiverem
sido bem-sucedidas, ou se uma única falha. Falando em falha, o assunto do próximo vídeo é
analisar como podemos lidar com
erros usando async await.
63. Manuseio de erros: Este vídeo
mostrará algumas maneiras de
lidar com erros em
seu código assíncrono. O código é ótimo quando
todas as coisas correm bem, mas quando as coisas não acontecem,
precisamos lidar com o que fazer. Alguns dos
métodos de promessa que analisamos nos dão algum tratamento de erros. Por exemplo, o método all
falhará se uma promessa falhar, portanto, temos algumas opções lá, mas também precisamos lidar com
todas as outras situações também, seja um manipulador de erros geral ou lidando com cada solicitação
específica. No projeto inicial, no arquivo de tratamento de erros, temos um elemento de
imagem vazio
na parte superior e também uma
única função. Nada de novo aqui
para esta função, isso é apenas pegar um
URL de imagem usando a API Fetch. Esperamos que os dados voltem, que são armazenados em resposta. Em seguida, extraímos esses
dados por meio do método JSON
e, em seguida, retornamos
a propriedade image que contém o URL. Pouco antes,
usamos essa função, vamos dar uma olhada em
outro exemplo simples. Logo abaixo, vamos criar uma
nova função com qualquer nome, e tudo isso
vai fazer é
retornar qualquer string simples. Depois disso,
registraremos o valor de retorno do console, chamamos nossa função,
abriremos no navegador e há nossa mensagem de retorno. Nada de inesperado aqui, mas se marcarmos essa
função como assíncrona,
então, pouco antes da palavra
função, marque isso como assíncrono, e desta vez
recuperaremos uma promessa. Vamos deixar
essa função lá, mas tenha isso em
mente por um momento. Assim que marcarmos uma
função como assíncrona, ela retornará uma promessa. Sabemos que temos uma função
para capturar o URL da imagem, então vamos criar uma segunda
função que realmente definirá o URL da imagem
através desse elemento de imagem. Isso também pode ser assíncrono,
chame esse setImage. Então, no interior, tudo o que
vamos fazer é pegar nossos elementos de imagem
com o
seletor document.query e definir
a origem igual ao valor
de retorno da função acima. Começo com o elemento de imagem e defino a fonte igual à nossa função acima,
que é getImageURL. Precisamos chamar isso. A função
GetImageURL é assíncrona,
então precisamos aguardar essa promessa ser
retornada antes que
possamos realmente usá-la. Vamos esperar que esta
função retornasse o valor. Tudo isso está ativado,
já que marcamos função
dele como assíncrona. Vamos chamar isso logo
abaixo, setImage. Anteriormente, ao lidar com
erros usando promessas, simplesmente
encadeamos em uma
seção de captura à promessa. Essa função setImage
também é assíncrona também, que também retorna uma promessa como vimos antes
com o exemplo simples, significa que poderíamos
encadear no final, então todo o bloco catch
que é vai correr em seguida. Podemos encadear isso no final, certificando-se de que não há ponto e
vírgula, add catch. Catch executará uma
função que recebe a mensagem de erro
e a colocará em um registro de console a mensagem de “noooo” e também
uma segunda com esse erro. Agora, vamos ver o que acontece se tentarmos chamar essa função. Recebemos de volta o erro que
capturaríamos ou definimos a imagem. Essa
chamada em particular foi um sucesso, então vemos a imagem
retornada. Para testar o bloco de captura, precisamos
desligar a rede como fizemos anteriormente, então vá para a guia Rede. Aqui embaixo, vamos definir as predefinições para ficar offline, agora podemos atualizar,
não vemos a imagem. Pule para o console. Nosso primeiro log do console e nosso segundo log do console não
conseguiram buscar. Vemos que isso funciona
bem e estamos misturando a sintaxe do assíncrono
aguardar com promessas. Se quiséssemos apenas manter
a sintaxe da promessa ou mover o tratamento de erros
para a própria função, poderíamos usar algo
chamado try and catch. Tente pegar, como parece, tentará fazer algo,
e se funcionar,
isso é tudo ótimo, se não, pegamos o erro e lidamos com ele da maneira que você quiser. Vamos remover a
seção catch do setImage
e, em seguida, dentro da nossa função
setImage, criamos um try-block
e abaixo de um bloco catch, que também
receberá a mensagem de erro. Isso é razoavelmente simples, tudo o que precisamos fazer é mover nosso código que você deseja executar dentro do
bloco try, então corte isso, cole isso na seção try
e, em seguida, dentro da captura área, podemos colocar nos
mesmos logs do console, modo que uma string e também um segundo log de console com a mensagem de erro que é
passada para esta função. Vamos salvar isso
e experimentar isso. Tenha em mente que minha rede ainda
está desativada, então, se tentarmos novamente,
não vemos a imagem, você verá nossas duas
mensagens de erro dentro do console. Vamos tentar ligar
isso novamente, retornar a rede, a
imagem agora é retornada e não vemos nenhum desses registros
do console sendo executado dentro daqui. Esta seção try and catch
está sendo executada de forma síncrona, então vamos executar a primeira
seção que é try. Se tudo isso funcionar,
está tudo
bem , mas se falhar, ele se moverá para o próximo bloco catch e executará o código contido
dentro de lá. Além disso, também
temos uma seção 2 finalmente. Isso funciona exatamente como quando
acorrentamos finalmente
ao final de uma promessa. Finalmente, sempre será
executado independentemente se a promessa foi
cumprida ou rejeitada. Na parte inferior, passe finalmente, e vamos colocar em
um simples registro de console. Vamos tentar isso,
atualizar e vemos o log do console com o
texto de sempre executa. Assim como uma nota lateral rápida, a captura ou o
bloco finalmente precisam estar presentes. Deve ter pelo menos
um desses no lugar,
ou, assim como este
exemplo, podemos usar ambos. Isso é bom para a captura
geral de erros, mas e se
quisermos saber qual parte do código
try falhou? No momento, isso é
bem simples porque só
temos uma linha de código. Mas e se essa
seção de tentativa fizesse mais do que isso? Para isso, poderíamos encadear um bloco
catch diretamente
na tarefa assíncrona e,
para ver um exemplo ,
vou copiar
essa função completa, comentar isso para referência e colá-lo abaixo. Podemos remover todo o tratamento
de erros
que acabamos de adicionar, que inclui o
catch, o finalmente e também o try-block deixando
nossa função assíncrona simples. Com isso, podemos então
remover o ponto e vírgula, podemos então pegar
a cadeia no final, dentro da captura, poderíamos passar uma função
diretamente dentro, ou se quiséssemos
reutilizar essa função, poderíamos fazer um
função separada dentro do nosso código. Vamos criar uma função logo
acima chamada de erro de alça. Vamos apenas pegar nossas duas
mensagens de erro, colá-las. O erro também ocorrerá
na mensagem de erro, então podemos chamar isso
dentro de catch. Isso nos dá uma função
reutilizável separada, que podemos então encadear
no final de múltiplas promessas. Vamos
experimentar isso. Agora devemos ver nossas duas mensagens de erro. Se houver uma falha. Caso contrário, vemos a imagem,
isso funciona bem. Vamos tentar desligar a
rede mais uma vez, vá para o console, há nossas mensagens de erro
dentro daqui. É claro que um
registro de console não
seria suficiente em um aplicativo
do mundo real, talvez
gostaríamos de ocultar
a imagem se houvesse um erro ou até mesmo adicionar uma imagem de
suporte de lugar no lugar. Mas a chave aqui é fazer
algo em vez de apenas ver o site ou o detalhamento do
aplicativo. tratamento de erros é uma grande
parte do JavaScript assíncrono, e vemos alguns padrões comuns aqui que você pode
usar em seus projetos, que realmente melhorará
a funcionalidade e a experiência do usuário.
64. Saindo Tão Em Breve: Este primeiro projeto que encontramos na última seção
desta classe, é chamado Leaving So Soon, e contém
algum código inicial então vamos nos
concentrar no JavaScript. Este projeto é o que é
chamado de pop-up de intenção de saída. Um pop-up de intenção de saída
é basicamente uma maneira de chamar a atenção do usuário se ele tentar sair do site. Temos um HTML simples, temos nosso título
e, em seguida, temos essa seção pop-up
dentro de uma div. Se passarmos para o
projeto e atualizarmos, tudo o que
vemos atualmente é esse título. A ideia é que temos um site
simples como este e você pode ter visto esses tipos de sites
ao navegar online. Se você tentar mover o
mouse para cima
e tentar
fechar o navegador, e tentar
fechar o navegador, ou até mesmo pesquisar ou
navegar para longe do site, muitas vezes
você pode ver
um pop-up aparecer. Esse pop-up pode
conter informações. Ele pode conter um código de voucher
ou, geralmente, qualquer coisa para
manter o usuário em seu site. Não vemos esta seção pop-up porque se
examinarmos essa div, ela terá o ID do pop-up de saída. Dentro de nossas folhas de estilo, se dermos uma olhada
nesta seção, o tipo de exibição está
atualmente definido como nenhum. Se mudarmos isso para
ser flexível e atualizado, o plano de fundo
desaparecerá por causa da animação CSS, que temos
na parte inferior. Nosso pop-up agora aparece com
todo o texto dentro. O conteúdo dentro
desses sites ou dentro desse
pop-up é irrelevante. A ideia é que queremos
alternar essa
configuração de exibição quando o mouse do usuário sair da parte superior do navegador. Por enquanto, vamos voltar
à nossa folha de estilos, e eu vou ocultar isso por padrão. Então, começamos a trabalhar
dentro do nosso script, que já está vinculado
na parte inferior. Vamos abrir isso. Se você pensar sobre o que
queremos fazer aqui, não
há muitas tarefas
que precisamos executar. Vamos começar criando
uma função que será executada quando o mouse
sair da área da janela. Uma vez que o pop-up estiver realmente sendo exibido
dentro do navegador, também
precisamos de uma
maneira de clicar
em um X no canto e
fechá-lo. Crie uma segunda função
chamada ClosePopup. Começaremos com
nossa primeira função, que é LeftWindow
e, para isso, precisamos ouvir um evento do mouse. Vamos
selecionar o documento
que é a nossa página da Web completa
e, em seguida, escutar quando o mouse
sair com o evento fora do mouse. Vamos pegar nossos documentos. Podemos adicionar um ouvinte de eventos. Eventos. Queremos ouvir
o mouse out, que então
acionará nossa função acima. Lembre-se, com eventos,
isso também recebe as informações do evento que
podemos acessar dentro de uma variável. Vamos começar registrando
isso no console. Registre as informações do evento
no console, atualize e
podemos ver se movemos o mouse para fora
da área de documentos, esse evento do mouse agora é acionado. Isso também funcionará se você
for para o outro lado, e também os
dois primeiros. Salte para aqui. As coordenadas do mouse
nas
quais estamos interessados são este ClientX
e o ClientY. Este é um valor de pixel
que nos dirá a localização do mouse assim que
este evento for disparado. Assim como quando olhamos para
a tela logo no início, X é a direção esquerda ou
direita, e o Y está de cima para baixo. Como estamos tentando tomar
cuidado com o mouse, deixando a parte superior do
navegador para fechar esta janela, estaremos interessados
na direção do clientY. Podemos filtrar isso,
e.Clienty. Vamos recarregar. Agora, se formos para o topo, podemos ver assim que passarmos pelo topo
da área do navegador, começamos a obter
um número negativo, o
que significa que o topo aqui
é o valor de zero. Precisamos ouvir
talvez uma área de 20 pixels, que exibirá tudo
pop-up assim que o usuário mover o mouse para a
área superior do navegador. Podemos remover o registro do console. Coloque em uma declaração if. Podemos dizer que se e.Clienty for menor do que qualquer valor de sua escolha, eu
vou para 20. Como vimos dentro
dessas folhas de estilo, podemos pegar nossos
elementos com o ID do
pop-up de saída e alternar
o tipo de exibição. Pegue isso com o
Document.querySelector. Eu envio o ID do pop-up de saída. Defina a propriedade style
do display como igual a flex.
Vamos experimentar isso. Atualize e agora vá para o topo, e este
acionará nosso pop-up. Você pode pensar que tudo isso
está funcionando bem e isso é
tudo o que precisamos fazer. Também precisamos
tomar algumas medidas para
que não irritemos o usuário. Precisa ativar esta cruz para que ela alterne nossa função
ClosePopup. Mas provavelmente só queremos
executar esse código para ativar o pop-up após
um certo período de tempo, e também queremos
garantir que isso seja
acionado apenas uma vez
na visita do usuário. Para garantir que isso seja acionado
apenas uma vez, faremos o inverso e
removeremos o ouvinte
de eventos dos documentos. Nos primeiros vídeos,
sabemos que precisamos
copiar as mesmas informações
do addEventListener. Ainda não podemos testar isso porque também
precisamos
fechar a janela antes
que possamos reativá-la. Faremos isso agora
entraremos na área ClosePopup
e, em seguida, faremos o oposto
definindo o tipo de exibição
como igual a nenhum. Para ativar essa função, precisamos ouvir
um clique em nossa cruz. Dentro da página de índice, a extensão contém
a área cruzada. Vamos pegar isso
dentro do nosso script, abaixo da parte inferior,
Document.querySelector. Selecionaremos nosso span.
Armazene isso dentro de uma constante chamada CloseBTN. Pegue os elementos, adicione
um ouvinte de eventos. Queremos ouvir
os eventos de clique, que executarão nossa função
acima. Vamos experimentar isso.
Mova para o topo para ativar o pop-up.
Clique na cruz. Também podemos ver se passamos
para o topo do navegador, nosso pop-up não é reativado porque removemos
o ouvinte de eventos. Tudo bem, isso está
funcionando muito bem. Mas uma
adição rápida que faremos é garantir que
o pop-up não seja ativado assim que o
usuário visitar o site. Se houver, por exemplo, digitado algo na parte superior e depois movido imediatamente, você não deseja que o pop-up
apareça imediatamente. O que faremos é
colocar um setTimeout para ativar essa função
somente
após um certo tempo de atraso. Chame um setTimeout. Passe em uma função onde
podemos mover nosso evento para fora do mouse, que aciona nossa função. Só chamará isso após um atraso de
tempo de três segundos. Experimente isso para que
possamos mover o mouse para cima nos
primeiros três segundos. Então, após três segundos, nossa função está ativa. Projeto bem simples, e podemos fazer bastante com uma pequena quantidade de código
JavaScript. É algo que
você pode achar útil ao criar sites
no futuro. Como será nosso próximo projeto, que será um carrossel de imagem, que construiremos
completamente do zero.
65. Imagem Carousel - Definir As Imagens: Em nosso próximo projeto,
vamos construir em um carrossel de imagens. Este
será o resultado final e é totalmente
construído com JavaScript. O que teremos é uma imagem
grande principal no topo. Podemos percorrer as imagens
inferiores para substituir isso usando as setas esquerda
e direita. Além disso, podemos pular para qualquer uma
dessas imagens
clicando nelas e
colocando-as na parte superior. Isso vai
reunir muitas
das habilidades que você
aprendeu e também verá
melhor como as coisas funcionam na prática com um aplicativo do mundo real. Vamos começar isso de novo
nos arquivos iniciais. Se saltarmos para
a próxima seção, que é o carrossel de imagem, temos algum código inicial. Temos uma página de índice muito
simples, estaremos injetando todo o
conteúdo por JavaScript. Tudo o que temos é uma
div vazia com a identificação do carrossel. Colocaremos em todo o conteúdo da
imagem
e, em seguida, vincularemos
ao nosso script. O script está dentro
da pasta carrossel, que contém nossas imagens, nossas folhas de estilo e também o JavaScript
para que isso funcione. Fornecido com este curso há cinco
imagens diferentes que você pode substituir e também alguns CSS básicos. Acabamos de ter um estilo
básico. Por exemplo, definimos o carrossel
principal para ter uma certa largura e
também
o colocamos no centro com margem 0 auto. Temos alguns efeitos de paira. Fora isso, algum
estilo geral junto com a classe
pequena e grande que temos aqui. Vamos adicionar essas classes
menores do que grandes a cada uma dessas imagens para que elas
se encaixem perfeitamente na tela. Vamos começar. Nós saltamos para
o nosso carousel.js vazio. Começaremos pegando esta
seção div de carrossel e também criaremos uma matriz com
todas as imagens. Pule para o carousel.js. Começaremos criando
uma matriz de nossas imagens. Cada um deles
será uma string que aponta para o URL dentro da pasta de
imagens. Se você usou
suas próprias imagens, lembre-se de alterar
os nomes dentro daqui para corresponder aos
que você colocou dentro. O primeiro, está
na pasta carrossel, e o caminho do arquivo é
images/beach.jpg. Vamos duplicar isso para
nos dar cinco imagens diferentes. O segundo era
elefantes. Temos grama. Temos lago, e
o último é a cidade. Em seguida, vamos pegar uma
referência ao nosso carrossel. Armazenaremos isso dentro de
uma constante chamada wrapper é igual ao seletor
document.query, mais no id do carrossel. No próximo passo, vamos
criar uma função que irá capturar todas essas imagens, irá fazer um loop sobre elas e
colocá-las na tela. Então crie uma função
abaixo chamada SetImages. O primeiro passo dentro
dessa função é
pegar nosso invólucro e limparemos
qualquer conteúdo existente. Isso é para que possamos repetir o processo de
configuração de nossas imagens, mas às vezes elas estarão
em uma ordem diferente. Limparemos todas as imagens
extras pegando nosso invólucro e definindo o HTML interno como
uma string vazia. Antes que eu esqueça, chamaremos
nossa função a partir de baixo, e então ela pega nossas
imagens e criaremos um loop para
cada um deles, images.foreach, além da função
interna. Criaremos uma referência para cada uma delas e chamaremos fonte de
imagem, ImageSRC. Abra o corpo da função
e, em seguida, dentro
daqui, vamos
criar um novo elemento de imagem, armazená-lo dentro de uma variável chamada elements,
documents.CreateElement. Escreva um elemento de imagem. Em seguida, precisamos definir a fonte do elemento de
imagem para ser igual a essa variável. Pegue nosso elemento, defina o atributo source como
igual à nossa fonte de imagem. Podemos então pegar nosso invólucro, que armazenamos
dentro dessa constante, então podemos adicionar a
este novo elemento, Wrapper.AppenChild, além de nosso elemento
recém-construído. Vamos até o navegador
e ver o que temos. Temos nossas cinco
imagens diferentes desse loop, mas se dermos uma
olhada na versão final, não
queremos apenas
cinco imagens aleatórias colocadas dentro do contêiner. O que queremos fazer é tornar
a primeira imagem grande
e, em seguida, criar uma seção
separada na parte inferior com as imagens pequenas restantes. Para fazer isso, criaremos um invólucro para todas as
imagens pequenas na parte inferior
e, em seguida, ele separará
isso do lugar uma pequena
imagem dentro daqui, e a imagem grande na parte superior. Primeiro, vamos voltar para nossa função e criar um novo invólucro para as quatro
pequenas imagens na parte inferior. Logo depois de onde limpamos
nossa parte superior e criamos uma nova constante chamada
SmalImageWrapper. Isso é igual a
document.createElement. Isso pode ser qualquer
elemento que você queira, como uma div ou uma seção, não
importa. Em seguida, pegue nossa seção e daremos a isso um
ID exclusivo do SmalImageWrapper. Agora, o que queremos
fazer é fazer um loop sobre todas as cinco
imagens da matriz. O primeiro precisa
ser colocado no invólucro
e, em seguida, todas as quatro imagens
restantes precisam ser colocadas dentro do
nosso invólucro de imagem pequeno. A maneira como podemos fazer isso
é primeiro selecionando nosso invólucro completo e verificando se ele tem
algum conteúdo atual. Se ele ainda não tiver um elemento de imagem atribuído
a esse wrapper, isso significa que é uma
primeira imagem na matriz. O que podemos fazer
dentro do nosso loop é que podemos colocar em
uma declaração if, e podemos verificar se nosso invólucro não
tem nenhum nó filho. Podemos
dizer! Wrapper.hasChildNodes. O código dentro daqui
só será executado se esse invólucro estiver vazio e não contiver
imagens adicionais dentro. Esse sempre será o
caso se estivermos
percorrendo e na primeira imagem. Se esse for o caso,
queremos definir a classe. Se olharmos para nossas folhas de estilo, queremos definir essa
classe de grande porque isso tem uma largura de 100%. Caso contrário, adicionaremos
a classe de pequeno, o que lhe dá
esse tamanho menor. É adicionar uma classe, podemos pegar nossos elements.classlist.add, colocar na classe de grande e também a classe de carrossel. Essa classe de carrossel, se voltarmos novamente à folha de estilos, transformará o cursor
em um ponteiro quando o usuário passar o mouse sobre a imagem. Este só deve se aplicar ao primeiro elemento
dentro do nosso invólucro, caso
contrário, ele deve ser aplicado para
as quatro imagens restantes. Vamos adicionar uma lista de classes pequenas. Vamos adicionar todos pequenos
e também carrossel. Ainda obtemos o efeito de focalização, mas desta vez como
estamos lidando com as quatro imagens menores, não
queremos adicioná-las
ao invólucro principal. Em vez disso, queremos adicioná-los ao nosso pequeno invólucro de imagens
que acabamos de criar. Então, vamos pegar isso, abrir criança, colocando nossos elementos. Vamos salvar isso
e experimentar isso. Lá vamos nós. Há
nossa imagem grande e as quatro pequenas imagens
nessas div separadas. Assim como uma recapitulação, o que
fizemos aqui é que criamos um invólucro grande para
toda a nossa seção. Criamos uma função
chamada set images. Assim que isso for executado,
ele limpará qualquer conteúdo existente
do invólucro, o que significa que quando estivermos em
loop sobre nossas imagens, se esse invólucro estiver vazio, isso significa que é um
primeiro elemento em a matriz, portanto, damos a
ela a classe grande. Caso contrário, são as quatro
imagens restantes em que
adicionamos o cluster de pequenas e também colocamos isso
em uma div separada. Este é um bom primeiro
estágio para o nosso projeto. Nos próximos vídeos, vamos dar uma olhada em
várias outras funções como reordenar essas imagens, como trocar as imagens ao redor e também como colocar nas
setas para ir para a esquerda e para a direita.
66. Imagem Carousel- Criando As Setas: Estamos no palco agora dentro
do nosso projeto, onde
temos todas as cinco imagens
exibidas na tela. Temos uma
imagem de recurso grande na parte superior, depois de quatro
miniaturas menores abaixo. Temos algumas
melhorias a fazer, queremos poder
clicar em qualquer uma dessas imagens menores e lugares na
seção em destaque na parte superior. Também queremos poder girá-los
ao redor
adicionando uma pequena seta à
esquerda e também para a direita. Vamos começar com isso adicionando as
setas assim que as imagens forem carregadas. Para fazer isso, podemos colocá-los em uma
função autônoma e chamar isso. Deixe-me chamar nossas imagens. Bem na parte inferior
desta função, chamaremos nossa
função, que
vamos chamar de SetArrows. Esta é a função
que criaremos a seguir. Logo abaixo, isso configura nossa
função, que era SetArrows. SetArrows não precisa tomar nada como parâmetro, então o que precisamos fazer aqui é que podemos criar
alguns ícones usando entidades
HTML e
armazená-los como o HTML interno
de um elemento span. O que precisamos é de duas constantes, a primeira é a seta para a
esquerda apenas igual a document.createElement
como em uma extensão. A razão pela qual estamos usando
o span é porque, por padrão, esse é um elemento
embutido, para que possamos colocá-los em linha
com nossas quatro imagens. A seta para a esquerda, vamos
acessar essas constantes e definir o HTML interno
para ser igual à nossa entidade HTML e o
código para a seta para a esquerda é o ‹ Ambas as setas, você
precisa clicar nestas e reordene todas as nossas imagens. Selecionaremos nossas
constantes e adicionaremos um ouvinte de eventos
agora é um clique gratuito, o que
acionará uma função. Ainda não criamos
essa função, mas ela será chamada de ReOrder e só para não
lançarmos nenhum erro, criaremos essa
função acima. Isso não precisa
ter nenhum conteúdo, voltaremos a isso. Logo abaixo do
nosso ouvinte de eventos , faremos praticamente o mesmo, mas desta vez para
a seta para a direita, criaremos os
elementos de extensão com o documento. CreateElement, defina
o HTML interno, rightArrow.innerHTML. O código da entidade HTML para
a seta para a direita é ›, que é apenas um para cima
da seta para a esquerda. Adicione um ouvinte de eventos. também
está
escutando um evento de clique, que acionará
a mesma função. Essas são nossas duas setas criadas com o conteúdo
e o ouvinte do evento. Mas o que agora precisamos fazer
é adicionar ambos
a uma determinada seção. Se voltarmos à
nossa primeira função que foi SetImages, temos este SmalImageWrapper. Esta é uma seção div
que contém mais de quatro pequenas miniaturas, então adicionaremos
ambas a esta seção. A maneira como podemos fazer isso
no início e no final, é usar um
método JavaScript chamado appendChild, que adicionará isso ao final da div colocada à direita. Então, para a seta para a esquerda, podemos usar o método prepend, que adicionará isso ao
início da nossa div. Vamos fazer isso na parte inferior
da nossa função setArrows. Vamos primeiro pegar a seção,
então, no interior de uma constante
chamada SmalImageWrapper, o Document.querySelector, isso tem o ID de
SmalImageWrapper. Pegue esta seção. Como
acabei de mencionar, colocaremos a seta para a
direita neste conteúdo
com AppendChild, como procuramos anteriormente. Isso adicionará isso
ao final da nossa seção div
após nossas imagens. Coloque em nossa seta para a direita, depois vamos adicionar nossa
seta para a esquerda no início, usaremos o método prepend
e inseriremos nossa seta para a esquerda. Vamos tentar isso. Agora, após atualização, ainda não vemos
nossas setas na tela. Vamos dar uma olhada
no console e ver se isso nos dá alguma pista. Dentro daqui podemos
ver que não podemos ler propriedades de null,
lendo appendChild, então quando tentamos acrescentar um novo elemento ao nosso invólucro de imagem
única, parece
que estamos tendo um problema. A razão pela qual isso acontece
é porque temos um SmalImageWrapper que
estamos criando no topo. Quando definimos nossas imagens, temos o
invólucro principal que contém nosso carrossel completo e, em seguida, temos nosso SmalImageWrapper, que estamos tentando selecionar
por esse ID dentro do loop. Mas cada uma de nossas imagens, estamos criando
novos elementos de imagem armazenados nessa variável, adicionamos a classe
grande ou a pequena
e, se for uma imagem pequena, adicionamos essas
quatro imagens pequenas para este SmalliImageWWRAPPER. Mas atualmente, não
estamos adicionando um SmalImageWrapper
ao DOM,
tudo o que estamos fazendo é
criá-lo e estamos adicionando
nossos quatro elementos, mas não estamos
colocando isso dentro do DOM. Pelo menos então, podemos selecionar para
baixo na parte inferior. A única vez
que algo está sendo adicionado ao DOM é quando adicionamos ao nosso invólucro
esse elemento. Adicionar o elemento diretamente ao nosso invólucro é completamente
bom se esta for a imagem grande porque
ele vai entrar diretamente
no carrossel principal. No entanto,
no entanto, quando estamos lidando com uma imagem pequena, queremos atribuir esses SmalImageWrapper
a esta seção. A maneira como podemos fazer
isso é selecionando nosso elemento e definindo isso igual
ao nosso SmalImageWrapper. Este SmalImageWrapper
conterá todas as nossas quatro pequenas imagens e , em seguida, adicionaremos isso
ao nosso invólucro principal. Agora, se salvarmos isso e atualizarmos,
agora podemos abrir isso, vemos nossas duas setas saltar para os elementos e,
se entrarmos no corpo, vemos nosso invólucro principal
com id de carrossel. Podemos abrir isso. Vemos nossa primeira imagem com
a classe de grande. Só para esclarecer,
este é atribuído porque assim que
começamos a percorrer
todas as nossas imagens, verificamos se esta
seção está vazia, se é maior
com a classe de grande e adicione isso
ao nosso invólucro. Caso contrário, as quatro imagens
restantes obterão a classe pequena e, em seguida, adicionarão
ao nosso SmalImageWrapper, que será passado para nossos elementos e, em seguida,
podemos adicioná-los ao DOM, o que podemos ver se nós
olhe para esta div aqui. Podemos abrir isso. nosso elemento span que
acabamos de adicionar com prepend, temos nossas quatro
imagens e, em seguida, o período final que
adicionamos com AppendChild.
67. Imagem Carrossel - Reordenação de Imagens: Anteriormente, configuramos nossas setas para a
esquerda e para a direita e também as vinculamos a uma
função chamada reordenar. Fizemos isso criando nossas setas dentro
dessa função, usando nosso evento for a click, que nele acionou
nossa função. O que vamos fazer agora é basicamente criar uma nova matriz. Essa nova matriz será construída reorganizando a ordem
de todas essas imagens. Faremos isso dentro
de nossa função primeiro pegando as
informações do evento a partir do clique, e o motivo pelo qual estamos fazendo
isso é porque precisamos determinar qual desses
botões foi clicado. Precisamos saber se é o
botão esquerdo ou o botão direito. Podemos fazer isso adicionando um
ID a cada um deles, então o Leftarrow.ID é
simplesmente igual à esquerda. Então vá para a
direita.ID à direita. Agora podemos acessar esse ID
pelas informações dos elementos
do evento. Sabemos anteriormente, fazendo um log do console, se registrarmos o valor de e.target, obtemos os elementos reais
dentro do console. Clique em qualquer um deles, obtenha o botão direito e,
em seguida, o botão esquerdo. Também podemos filtrar esse objeto
, pegar apenas o ID. Isso agora nos dá um ponteiro
exclusivo sobre qual botão foi pressionado. Agora podemos remover isso
de um registro de console, armazená-lo dentro de uma
constante chamada direção. Agora, o que vamos
fazer é fazer um loop sobre nossa matriz
de imagens no topo. Vamos nos certificar de que cobrimos
todas essas cinco imagens. Em seguida, determinaremos se o botão esquerdo ou o
botão direito foi clicado
e, em seguida, usaremos isso
para reordenar nossas imagens. Essas novas imagens serão armazenadas dentro de uma nova matriz
chamada NewRay, que terá o
valor inicial de uma matriz vazia, e então podemos fazer um loop
sobre todas as nossas imagens. Faça isso com um loop forEach, passe nossa função. Então, dentro
dessa função, ela vai levar duas coisas. Primeiro, como sempre
passaremos um nome de variável, que será cada
imagem nesse loop específico, e então também podemos
acessar o número do índice. Para o primeiro loop, este será o primeiro item, que é a nossa praia com número de
índice 0. Em seguida, isso será incrementado
um em cada loop. Para reorganizar essas imagens, precisamos primeiro verificar se a direção
começará com a esquerda. Caso contrário, adicionaremos uma seção
else que será executada se a direção
for igual à direita. Vamos pensar sobre
o que queremos
fazer se a direção for deixada. Se este botão esquerdo
for clicado, precisamos percorrer a matriz
original que estamos fazendo e, para o
primeiro item dentro daqui, queremos empurrar isso até
o final de nossa nova matriz
e, em seguida, para as quatro imagens restantes na parte inferior, queremos mudar essas para
trás em uma posição. Podemos fazer isso dentro
do botão esquerdo. Verificaremos se o
número do índice que terá acesso aqui
é igual a 0,
então, ou seja, é a principal imagem em
destaque na parte superior. Se for esse o caso,
queremos empurrá-lo até o final do nosso novo array. Podemos fazer isso
acessando essa variável. Podemos posicionar isso
no final
acessando nossa propriedade
images.length. Para este exemplo, esse deve ser nosso novo array no
índice Posição 5. Vamos definir essa como
a primeira imagem. Pegando nossa primeira imagem
da matriz original ou
empurrando-a para o final do nosso novo. Também chamaremos de
NEWarray.SHIFT caso
haja algo no
início desta matriz. Esta é a primeira
imagem cuidada, mas e as quatro
restantes? Bem, para as quatro imagens
restantes, tudo o que precisamos fazer é pegar o número do índice atual
e mudar isso de volta em um. Podemos fazer isso dentro de
uma seção else logo após se, colocando outro. Este será o caso das quatro imagens restantes. Tudo o que queremos
fazer é pegar nossa nova matriz, selecionar o índice atual
adotar o valor de um e definir isso igual à
nossa imagem atual. Por exemplo, se nossa
imagem atual for o índice Número 3, ela será movida de
volta para o Número 2, e isso será o mesmo para
as quatro imagens restantes. Antes de prosseguirmos,
vamos experimentar isso. Atualmente, nossa função está sendo chamada e está
reordenando a matriz, também
precisaremos substituir
a matriz de imagens original pelo nosso novo. Podemos fazer isso na
parte inferior da nossa função, definir nossa matriz de imagens como
igual à nova matriz. Além disso, uma vez que
redefinimos
nossa matriz de imagens, precisamos chamar a função
set images, que está realmente fazendo um loop sobre essa matriz e
exibindo-as na tela. Faremos isso na parte inferior. Chame essa função e
vamos tentar isso. Atualizar. Se clicarmos
na “Seta para a direita”, obteremos
um erro porque ainda não lidamos com
esse caso. Vamos tentar para a esquerda. Temos os elefantes, que agora se moveram para
a primeira posição de índice. Vamos clicar em “Esquerda” novamente.
Isso se moveu para o fim. Tudo isso parece
estar funcionando bem. Só para recapitular, estamos pegando
a primeira imagem e, em seguida, empurrando isso
no final de nossa nova matriz. Atualmente é a praia,
isso vai até o fim, e as quatro
imagens restantes serão movidas para
a esquerda por um número de índice. Em seguida, cuidaremos
da seção L, que é se o
botão direito tiver sido clicado. O que vamos fazer
aqui é basicamente o oposto desta
linha aqui. Precisamos, em vez remover um número de índice
para movê-lo para a esquerda, precisamos adicionar um para mover
cada um para a direita. Colaremos isso em, tudo
em um número de índice de um. Desta vez, em
vez de verificar se
estamos acessando a primeira imagem, precisamos verificar se estamos
acessando a última imagem. Se for a última imagem, ela
precisará ser removida
do final da matriz e
colocada no início. Podemos fazer isso dentro
de uma seção if. Se o índice mais um for
igual a imagens ou comprimento. A razão pela qual fizemos
isso, porque lembrar números de
índice começam em 0, mas quando estamos acessando
o comprimento da matriz, esse será o número real. Atualmente, isso é 5, mas o número do índice
só sobe para 4, o que significa que precisamos mais 1. Verifique se isso
também é igual a 5. Portanto, se isso for igual a 5, esse é o nosso último
valor na matriz. Precisamos definir que isso seja
no início. O início
de nossa nova matriz será o índice Número 0, que podemos definir como
a imagem atual. Também como
fizemos quando removemos o primeiro item
da matriz, desta vez precisamos remover o último, Newarray.pop. Vamos salvar isso e
experimentar este. À direita, devemos ver as casas mudadas para o topo e a praia
se mudou para a esquerda. Bom. Agora o lago, a grama, os elefantes. Isso agora funciona completamente
bem em ambas as direções.
68. Imagem Carousel - Imagens de Troque: Nossa próxima e última tarefa
para este projeto é permitir que o usuário
clique em qualquer uma
dessas pequenas imagens em miniatura
e, em seguida, isso
será trocado pela
imagem principal em destaque na parte superior. A imagem pequena
será colocada
na seção grande e
a imagem grande será então suspensa
na área de miniatura. Para este, criamos
nossas pequenas imagens de qualquer função de imagens definidas
saltam para a seção else, onde adicionamos a classe de small. O que faremos aqui é adicionar um ouvinte de eventos a cada um. Logo após adicionarmos a classe. Antes de acrescentarmos
isso ao nosso wrapper, selecionaremos nossos elementos, adicionaremos um ouvinte de eventos, onde ouvimos o clique, que
acionará uma função que criará em apenas um
momento chamado SwapImages. Para baixo até o fundo. Nossa
função trocará imagens. Dentro daqui,
adicionamos o ouvinte de eventos, que irá
acionar essa função, cada vez que clicarmos em
uma das imagens pequenas, mas apenas como uma etapa de
precaução extra, adicionaremos uma instrução if
para retornar dessa função se a
imagem grande tiver sido clicada. O que faremos é, pois este
é um evento, clique em “Evento”, analisaremos as informações do
evento, acessaremos os
elementos com e.target. Em seguida, podemos verificar se
a ClassList contém, usando um método contém, a classe de large. Se isso acontecer,
retornaremos dessa função. Isso é apenas por nossa precaução. Em seguida, o que faremos é
pegar usando as
informações event.target, a imagem real que
foi clicada. Tudo o que precisamos fazer é pegar
o atributo source, descobrir qual
dessas imagens precisa ser colocada
na área em destaque. Podemos fazer isso,
instalar isso dentro de uma constante chamada fonte de imagem, definir isso igual a e.target. Usamos GetAttribute, onde
pegaremos a fonte. Agora temos essa fonte de imagem, que é o caminho do arquivo. Podemos usá-lo para pegar o número de
índice da nossa matriz. Vamos pegar nossa matriz de imagens. Em seguida, usaremos o
método chamado indexOf
e, em seguida, analisaremos em nossa fonte. Então, as imagens, indexOf, como no nome da nossa variável,
que é a fonte da imagem. Isso
retornará um número de índice que você pode armazenar dentro de uma constante chamada
SelectedImageIndex. O que temos agora é
o número
do índice da miniatura clicada. Agora precisamos trocar isso
com a imagem que está na posição de índice 0. Mas antes de realmente
fazermos essa troca, precisamos primeiro
armazenar qual imagem está atualmente na posição de índice 0. Armazenaremos isso dentro de uma
constante chamada FirstImage. Defina essas duas imagens
no índice número 0. Em seguida, podemos reatribuir a primeira imagem
original, então as imagens 0 agora
serão iguais às imagens e analisando esse índice de imagem
selecionado. Isso substitui a primeira imagem
pela miniatura clicada
e, em seguida, precisamos fazer
o inverso
selecionando, novamente, nossas imagens
no SelectedImageIndex. Troque isso pela nossa primeira imagem. Esta é uma razão pela qual
começamos originalmente o FirstImage porque
na próxima linha, estamos reatribuindo
a primeira imagem. Portanto, ele nos dá o valor
errado na parte inferior. No final, chamaremos
nossa função setImages, para reatualizar o navegador com
a nova ordem da matriz. Vamos experimentar isso
para a grama. A praia
cai até o fundo, vamos tentar esta. Bom. Isso agora conclui
nosso projeto de carrossel de imagens. Espero que você tenha gostado
e aprendido alguns truques novos ao longo do caminho.
69. Siga-me na Skillshare: Um grande parabéns
de mim por chegar ao fim desta aula. Espero que você tenha gostado
e tenha adquirido algum
conhecimento disso. Se você gostou desta aula, certifique-se de
conferir o resto das minhas aulas aqui no Skillshare, e também me siga para
quaisquer atualizações e também para
ser informado de novas aulas à medida que elas se tornarem disponíveis. Obrigado mais uma vez, boa sorte, e espero que eu o verei
novamente em uma aula futura.