JavaScript moderno para iniciantes: Parte 2 | Chris Dixon | Skillshare

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

JavaScript moderno para iniciantes: Parte 2

teacher avatar Chris Dixon, Web Developer & Online Teacher

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Apresentação

      2:23

    • 2.

      Baixar a pasta de projetos

      0:59

    • 3.

      Compartilhe seu trabalho em Skillshare!

      1:09

    • 4.

      Para laços

      10:18

    • 5.

      For...in & For...of

      6:25

    • 6.

      Enquanto & do...while

      5:22

    • 7.

      Se / outras declarações e aninhamento

      5:56

    • 8.

      Caso contrário,

      4:22

    • 9.

      A condicional switch

      7:57

    • 10.

      Operador condicional (ternário)

      4:12

    • 11.

      Tipo Coersão e conversão

      10:00

    • 12.

      Truthy & Falsey

      4:35

    • 13.

      Corrente opcional

      6:22

    • 14.

      Criando e modificando novos objetos

      5:47

    • 15.

      Função construtora de objetos

      9:21

    • 16.

      Protótipos de objetos

      6:41

    • 17.

      Herdando as propriedades de objetos

      10:09

    • 18.

      Copiando as propriedades de objetos

      4:38

    • 19.

      Objetos de estilo CSS

      4:35

    • 20.

      Usando loops em objetos

      9:26

    • 21.

      Objetos dinâmicos

      5:44

    • 22.

      Tipos primitivos e de referência

      5:27

    • 23.

      Comparação de objetos

      6:41

    • 24.

      Introdução da seção

      3:24

    • 25.

      Ordens de listagem

      12:30

    • 26.

      Refactor de ordens de listagem

      5:24

    • 27.

      Função auxiliar de elementos

      6:33

    • 28.

      Selecionando a ordem atual

      9:13

    • 29.

      Defina a Pizza Atual

      5:30

    • 30.

      Métodos de divisão e adesão

      10:50

    • 31.

      Adicionar Pizzas Ao Forno

      9:24

    • 32.

      Começar e terminar o jogo

      9:09

    • 33.

      Introdução À Matemática Javascript

      7:08

    • 34.

      Gerando novas pizzas com matemática

      8:36

    • 35.

      setInterval

      9:17

    • 36.

      setTimeout

      4:47

    • 37.

      Temporizadores de compensação

      3:56

    • 38.

      Introdução À Data De Javascript

      5:26

    • 39.

      Configurando o tempo de cozimento

      4:43

    • 40.

      Introdução À Canvas & Co-Ordinates

      13:03

    • 41.

      Configurar os ingredientes

      7:45

    • 42.

      Desenhar ingredientes circulares

      6:38

    • 43.

      Desenhando várias peças

      13:00

    • 44.

      Limpar a tela

      4:33

    • 45.

      Pizzas de desperdício

      2:35

    • 46.

      Etapas de verificação

      16:23

    • 47.

      Concluindo ordens

      12:48

    • 48.

      Remover ordens

      3:33

    • 49.

      Atualizando a IU e estatísticas

      9:55

    • 50.

      Introdução ao escopo

      5:49

    • 51.

      Âmbito de aninhamento

      5:35

    • 52.

      Âmbito de bloqueio e função

      3:35

    • 53.

      Grua

      7:48

    • 54.

      Zona morta temporal

      5:17

    • 55.

      Fechamentos

      9:34

    • 56.

      Um pouco de fundo

      6:25

    • 57.

      Funções de retorno de chamada

      15:20

    • 58.

      Promessas

      11:23

    • 59.

      O Construtor Promessa

      7:51

    • 60.

      Trata de várias promessas

      7:15

    • 61.

      Async / espera

      6:42

    • 62.

      Manuseio de múltiplas esperas

      4:02

    • 63.

      Manuseio de erros

      8:49

    • 64.

      Saindo Tão logo

      8:01

    • 65.

      Imagem Carousel- Configurando as imagens

      9:15

    • 66.

      Imagem Carrossel- Criando as setas

      7:01

    • 67.

      Carrossel de imagens - Imagens de Re-Ordering

      8:11

    • 68.

      Imagens de troca de carousel

      4:04

    • 69.

      Siga-me na Skillshare

      0:23

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

378

Estudantes

13

Projetos

Sobre este curso

Bem-vindo ao JavaScript moderno para iniciantes!

Esta é a parte 2 do curso, com base na fundação que você aprendeu na parte 1. Se você não tomou parte 1, não se esqueça de passar por esse curso primeiro, a menos que você já tenha alguma experiência em JavaScript e você queira cobrir os tópicos nesta seção.

Seu projeto inicial desde a primeira parte vai continuar nesse curso, se você não o tem, pode baixá-lo aqui:

Pegue os arquivos iniciais aqui.

As etapas do projeto Speedy Chef podem ser encontradas aqui.

Aprender qualquer nova habilidade pode ser difícil e o Javascript não é exceção!

O Javascript tem uma vasta gama de recursos e coisas que pode fazer, significando às vezes como iniciantes não temos ideia por onde começar.

Foi por isso que criei esse curso…

Esse curso abrange muitos assuntos JavaScript, incluindo loops e instruções condicionais, um olhar profundo para objetos, matemáticas, data e temporizadores, e desenho para a tela.

Isso é tudo enquanto olha para exemplos e demonstrações do mundo real, juntamente com a criação de um jogo de chef de pizza para combinar muitas partes do que você aprendeu. Esse projeto será razoavelmente grande, mas vamos dividi-lo em seções gerenciáveis.

Mais tarde, descobrimos algumas das partes mais complicadas, como o JavaScript assíncrono, escopo, elevação e fechamentos, antes de terminar com mais 2 projetos, Criamos um pequeno aplicativo chamado sair tão cedo, que é um popup de intenção de saída para atrair os visitantes com uma oferta quando eles tentam sair do seu site. Antes de completar o curso com uma carousel. de imagem JavaScript totalmente funcional.

Obrigado pelo seu interesse nesse curso, e vou vê-lo na primeira aula…

Conheça seu professor

Teacher Profile Image

Chris Dixon

Web Developer & Online Teacher

Professor

Hello, My name is Chris and I am a Web Developer from the UK. I am an experienced trainer leading web development bootcamps and also teaching online courses.

My main areas of interest are Vue.js, Nuxt.js, Shopify, JavaScript, eCommerce, and business. I am passionate about what I do and about teaching others.

Whatever your reason for learning to build websites you have made an excellent career choice.

My personal motivation was to become my own boss and have more freedom and flexibility in my life. I also enjoy the technical challenge it provides and the way it constantly evolves. I built my first website back in 1999 and I have watched the web evolve into what it is today.

I try to make my courses enjoyable and try to remember what it was like when I was lea... Visualizar o perfil completo

Level: Intermediate

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

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.