Pular para o conteúdo
murad.guide

Introdução Completa à Web

Capítulo 18

Contexto this e arrays

5 min de leitura 861 palavras 2 gravuras

O capítulo 17 juntou dados num objeto. Agora dois assuntos: quem é this quando um método roda, e o array, a lista com ordem. Continua a Casa da Restinga em Natal. Esta é o capítulo 18 de 23.

O exemplo está em exemplos/18-this-arrays/. Abra index.html. A lista de pedidos na página vem de um array. O console mostra this no método do cliente.

Trabalhe na cópia inicio da etapa. Leia e digite o código; mude uma coisa. Antes de recarregar, anote sua previsão. Depois confira com a referência completa. Se nada mudar, confira o arquivo salvo e o caminho aberto. Blocos adicionais do capítulo podem ser digitados no console; o exemplo completo mostra a aplicação daquela etapa.

O que você vai aprender

this é quem está antes do ponto

Dentro de um método, this é o objeto que você usou na chamada. Se escreve cliente.endereco(), lá dentro this é cliente.

Não é magia. Olhe o ponto na hora de chamar. O que está à esquerda vira o contexto.

const cliente = {
  nome: "Lia",
  cidade: "Natal",
  apresentar() {
    return this.nome + " em " + this.cidade;
  }
};
console.log(cliente.apresentar());

A frase vira Lia em Natal. this.nome é a chave nome daquele objeto.

Por agora, ignore window, bind e arrow function. A regra curta basta: método chamado com ponto → this é o objeto.

Pare e experimente. Troque "Lia" por "Duda". Preveja Duda em Natal. Recarregue. Confira.

Erro comum: copiar só apresentar para uma variável e chamar solto(). Sem o objeto à esquerda, this deixa de ser o cliente e as chaves vêm vazias.

Endereço da Restinga com this

Um objeto aninhado descreve o envio do café. O método lê this para montar o texto.

const entrega = {
  nome: { primeiro: "Nara", ultimo: "Costa" },
  local: {
    rua: "Rua das Dunas",
    numero: 120,
    cidade: "Natal",
    uf: "RN"
  },
  endereco() {
    return this.nome.primeiro + " " + this.nome.ultimo + "\n" +
      this.local.rua + ", " + this.local.numero + "\n" +
      this.local.cidade + " — " + this.local.uf;
  }
};
console.log(entrega.endereco());

\n é quebra de linha no texto. O método não recebe parâmetros: tudo que precisa já está no objeto.

Pare e experimente. Mude numero para 200. Preveja a rua com 200. Recarregue. Confira o console.

Erro comum: escrever nome.primeiro sem this. Lá dentro não existe uma variável nome. Existe this.nome.

this aponta para quem chamou; o array guarda a ordem

Array: lista com ordem

Objeto não promete ordem das chaves. Array promete: o primeiro item é o índice 0.

const dias = [
  "segunda",
  "terça",
  "quarta",
  "quinta",
  "sexta",
  "sábado",
  "domingo"
];
console.log(dias);
console.log(dias[0]);
console.log(dias[1]);
console.log(dias[6]);

Os colchetes [] criam a lista. Dentro cabe string, número, objeto, até outro array.

dias[0] é "segunda". Não existe dias[7]: o sétimo dia está no índice 6.

Pare e experimente. Imprima dias[3]. Preveja "quinta". Recarregue. Confira.

Erro comum: pedir dias[1] achando que é o primeiro. O primeiro é sempre 0.

length, join e push

length é o tamanho. join cola tudo numa string. push acrescenta no fim.

const primos = [1, 2, 3, 5, 7, 11];
console.log(primos.length);
console.log(primos.join(" | "));

Seis itens → length é 6. O join devolve "1 | 2 | 3 | 5 | 7 | 11".

const pedidos = [
  { item: "Café coado", mesa: 1 },
  { item: "Tapioca", mesa: 2 }
];
pedidos.push({ item: "Suco de caju", mesa: 3 });
pedidos[1] = { item: "Tapioca de queijo", mesa: 2 };

push não troca o que já estava. Atribuir pedidos[1] = … substitui o segundo item.

Pare e experimente. Dê push de { item: "Água", mesa: 4 }. Preveja length 4. Recarregue. Confira.

Erro comum: usar pedidos.length() com parênteses. length é propriedade, não função.

Percorrer com for

Você já tem for do capítulo 15. O padrão clássico usa o índice.

const bairros = ["Ponta Negra", "Redinha", "Ribeira", "Petrópolis"];

for (let i = 0; i < bairros.length; i += 1) {
  console.log(bairros[i]);
}

i começa em 0. O laço para quando i chega em length. Assim você visita cada item uma vez.

O HTML do exemplo lista os pedidos:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Pedidos — Casa da Restinga</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main>
    <h1>Pedidos da manhã</h1>
    <ul id="lista"></ul>
  </main>
  <script src="script.js"></script>
</body>
</html>

No script, cada volta cria um li e coloca em #lista.

Pare e experimente. Acrescente "Lagoa Nova" no array. Preveja um quinto item. Recarregue. Confira a lista.

Erro comum: escrever i <= bairros.length. Na última volta bairros[4] não existe num array de quatro itens. Aparece undefined.

Início da referência desta etapa no navegador local

forEach: o array chama a função

forEach é um método do array. Você entrega uma função. O array chama essa função uma vez por item.

bairros.forEach(function (bairro) {
  console.log(bairro);
});

bairro é o item daquela volta. O resultado visível é o mesmo do for. Enquanto estiver começando, prefira o for com índice. forEach aparece em códigos prontos: agora você reconhece.

As duas formas visitam a mesma lista. Nenhuma publica nada. Tudo corre no arquivo local.

Pare e experimente. Dentro do forEach, concatene " — Natal" ao log. Preveja quatro linhas com a cidade. Recarregue. Confira.

Erro comum: esquecer a função e escrever bairros.forEach(bairro). forEach exige uma função, não o item solto.

Atividades

  1. Em cliente.apresentar(), quem é this?
  2. Qual o índice de "domingo" no array dias do capítulo 3?
  3. push altera o array original ou devolve uma cópia?
  4. Por que i < lista.length e não i <= lista.length?

Respostas comentadas

  1. O objeto cliente. A chamada tem cliente à esquerda do ponto.
  2. 6. Sete dias, contagem a partir de zero.
  3. Altera o original: o novo item fica no fim. length aumenta um.
  4. O último índice válido é length - 1. Com <=, a última volta lê um buraco e imprime undefined.

MDN

O arquivo completo

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

experiments.js

const cliente = {
  nome: "Lia",
  cidade: "Natal",
  apresentar() {
    return this.nome + " em " + this.cidade;
  }
};
console.log(cliente.apresentar());
const pedidos = ["café coado", "bolo de caju", "leite de coco"];
console.log(pedidos[0]);
console.log(pedidos.length);
const lista = document.getElementById("lista");
if (lista) {
  for (const pedido of pedidos) {
    const li = document.createElement("li");
    li.textContent = pedido;
    lista.append(li);
  }
}

assets/stylesheets/main.css

*,
*::before,
*::after { box-sizing: border-box; }
html, body, h1, h2, h3, p, ul { margin: 0; padding: 0; }
img { max-width: 100%; height: auto; }
body {
  font-family: "Segoe UI", Tahoma, sans-serif;
  line-height: 1.5;
  color: #1a2a2c;
  background: #f7f3ea;
}
a { color: #0d5c63; }
a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 3px solid #c45c26;
  outline-offset: 3px;
}
.skip { position: absolute; left: -999px; }
.skip:focus { left: 0.5rem; top: 0.5rem; background: #fff; padding: 0.4rem 0.7rem; z-index: 2; }
.wrap { width: min(44rem, calc(100% - 2rem)); margin-inline: auto; }
header { background: #0d5c63; color: #fff; padding: 1rem 0; }
header a { color: #fff; }
.brand { font-weight: 700; text-decoration: none; }
nav ul { list-style: none; display: flex; gap: 1rem; margin-top: 0.5rem; }
nav a[aria-current="page"] { text-decoration: underline; text-underline-offset: 0.2em; }
main { padding: 1.5rem 0 3rem; }
footer { border-top: 1px solid #ddd4c4; padding: 1rem 0; font-size: 0.95rem; }
article { margin: 1.25rem 0; padding-bottom: 1rem; border-bottom: 1px solid #ddd4c4; }