Pular para o conteúdo
murad.guide

As Três Camadas

Capítulo 17

Objetos e arrays

5 min de leitura 843 palavras 1 gravura

Até aqui uma variável guardava um valor: um número, um texto, um verdadeiro ou falso. Na Oficina do Farol isso não basta. Uma oficina tem nome e vagas. Uma semana tem várias oficinas. Este capítulo ensina a juntar dados: o objeto para um registro, o array para uma lista ordenada.

O exemplo está em exemplos/17-objetos/. Abra index.html. A lista na página vem de um array de objetos. O console mostra os nomes com map.

Trabalhe na cópia inicio desta etapa. Leia e digite o código indicado; mude apenas uma coisa. Antes de recarregar, escreva o resultado que espera. Depois compare com a referência completa ao lado. Se algo falhar, confira primeiro o arquivo salvo e o caminho aberto.

O que você vai aprender

Um objeto é um registro

Um objeto agrupa informações que pertencem à mesma coisa. Cada campo tem um nome (a chave) e um valor.

const oficina = {
  nome: "Cerâmica",
  vagas: 12
};

console.log(oficina.nome);
console.log(oficina["vagas"]);

A primeira leitura usa ponto. Prefira essa forma quando o nome da chave é fixo. A segunda usa colchetes e uma string. Serve quando o nome vem de uma variável.

const campo = "nome";
console.log(oficina[campo]);

Erro comum: escrever oficina[nome] sem aspas e sem variável. O JavaScript procura uma variável nome. Se ela não existir, a página quebra.

Pare e experimente. No console do exemplo, digite oficinas[0].vagas = 11 e depois oficinas[0]. A vaga vira 11 sem recarregar. Recarregue a página: volta a 12, porque o arquivo não mudou.

Um array é uma lista ordenada

Um array guarda itens em ordem. Os colchetes [] criam a lista. O primeiro item fica no índice 0, não no 1.

const nomes = ["Cerâmica", "Xilogravura", "Fotografia"];
console.log(nomes[0]);
console.log(nomes[1]);
console.log(nomes[2]);
console.log(nomes.length);

length é o número de itens. Aqui vale 3. O último índice é length - 1. Pedir nomes[3] devolve undefined: não há quarto item.

Você pode guardar números, textos, objetos ou outros arrays. Na Oficina, o mais útil é um array de objetos:

const oficinas = [
  { nome: "Cerâmica", vagas: 12 },
  { nome: "Xilogravura", vagas: 8 },
  { nome: "Fotografia", vagas: 10 }
];

oficinas[0].nome é "Cerâmica". Primeiro o índice da lista, depois o campo do registro.

Lista ordenada no índice 0 e objeto com nome e vagas

Percorrer com for

Para mostrar cada oficina na página, um for combina o contador com length.

const lista = document.getElementById("lista");
for (let i = 0; i < oficinas.length; i += 1) {
  const item = document.createElement("li");
  item.textContent = `${oficinas[i].nome}: ${oficinas[i].vagas} vagas`;
  lista.append(item);
}

i começa em 0. Enquanto i for menor que o tamanho, o bloco roda. No fim, i += 1 avança. Sem esse avanço, o loop não termina e a aba trava.

createElement("li") cria um item de lista. textContent coloca texto visível, sem interpretar HTML. append encaixa o item dentro de ul.

Pare e experimente. Troque o texto do item para mostrar só o nome. Recarregue. A página deve listar três nomes, sem o número de vagas.

Transformar com map

map percorre o array e devolve outro array. Cada item vira o que a função retorna.

const soNomes = oficinas.map((oficina) => oficina.nome);
console.log(soNomes.join(", "));

A função recebe um item por vez. Aqui ela devolve só nome. soNomes fica ["Cerâmica", "Xilogravura", "Fotografia"]. join junta numa string, com vírgula no meio.

for é melhor quando você faz alguma coisa (criar li, somar, decidir). map é melhor quando você transforma a lista inteira. Os dois aparecem no exemplo. Use o que o problema pedir.

Erro comum: esquecer o return numa função map com chaves { }. Sem return, cada posição vira undefined. A seta curta (oficina) => oficina.nome já devolve o valor.

O que não misturar

Objeto descreve dados por chaves. Array descreve uma sequência por índices. Não use um objeto quando a posição importa. Não use um array de textos soltos quando cada item tem nome e vagas: use array de objetos.

const errado = { 0: "Cerâmica", 1: "Xilo" };
const certo = ["Cerâmica", "Xilo"];

O primeiro parece lista, mas não tem map nem length de array. O segundo é a lista de verdade.

Na próximo capítulo você vai receber testes que esperam arrays e valores. Saber índice 0 e length evita metade das falhas.

Atividades

  1. O que oficinas[0] devolve no array deste capítulo? E oficinas[0].vagas?
  2. Por que nomes[3] não quebra a página, só devolve undefined?
  3. Quando você usa ponto e quando usa colchetes para ler um objeto?
  4. No exemplo, acrescente { nome: "Bordado", vagas: 6 } no array. O que deve aparecer na lista depois de recarregar?

Respostas comentadas

  1. oficinas[0] é o objeto da cerâmica. oficinas[0].vagas é o número 12.
  2. O JavaScript não exige que o índice exista. Fora da lista, o valor é undefined. O erro aparece se você tratar isso como texto sem conferir.
  3. Ponto quando a chave é um nome fixo (oficina.nome). Colchetes quando a chave está numa string ou numa variável (oficina["nome"], oficina[campo]).
  4. Um quarto li com Bordado e 6 vagas. Se nada mudar, o arquivo salvo não é o que o navegador abriu, ou o servidor está em outra pasta.

Referências

O arquivo completo

Referência do exemplo 17-objetos, reproduzida aqui para que você possa conferir sem sair da página.

index.html

<!DOCTYPE html>

<html lang="pt-BR">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<title>Objetos e arrays</title>
<link href="lab.css" rel="stylesheet"/>
<style>body{overflow-wrap:anywhere}img,input,textarea,select,iframe{max-width:100%}img{height:auto}fieldset,.cartao{min-width:0}pre{max-width:100%;overflow:auto}:focus-visible{outline:3px solid #005fcc;outline-offset:3px}.atalho-conteudo{position:absolute;left:.5rem;top:-6rem;background:white;color:#172f50;padding:.5rem;z-index:999}.atalho-conteudo:focus{top:.5rem}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}</style></head>
<body><a class="atalho-conteudo" href="#conteudo">Pular para o conteúdo</a><main id="conteudo" tabindex="-1">
<h1>Objetos e arrays</h1>
<ul id="lista"></ul>

</main><script src="script.js"></script></body>
</html>

script.js

const oficinas = [
  { nome: "Cerâmica", vagas: 12 },
  { nome: "Xilogravura", vagas: 8 },
  { nome: "Fotografia", vagas: 10 },
];

const lista = document.getElementById("lista");
for (let i = 0; i < oficinas.length; i += 1) {
  const item = document.createElement("li");
  item.textContent = `${oficinas[i].nome}: ${oficinas[i].vagas} vagas`;
  lista.append(item);
}

const nomes = oficinas.map((oficina) => oficina.nome);
console.log(nomes.join(", "));