Objetos e JSON

Aprenda a modelar dados reais com objetos JavaScript: crie e altere propriedades, percorra-as e veja por que copiar uma variável não copia o objeto ao qual ela se refere. Dê comportamento aos objetos com métodos e descubra a que a palavra-chave this se refere em cada tipo de chamada. Extraia e combine dados com desestruturação, espalhamento e rest, armazene coleções em Map e Set e converta dados para texto JSON e de texto JSON com JSON.stringify e JSON.parse.

BásicoAula 4 de 9 do curso Curso de Programação em JavaScript

O que você vai aprender

  1. Descreva elementos do mundo real no código como objetos com propriedades nomeadas, leia e altere essas propriedades e compreenda como os objetos são armazenados, copiados e comparados.
    • Criar objetos e trabalhar com suas propriedades
      Escreva literais de objeto, leia propriedades com as notações de ponto e de colchetes e adicione, altere e exclua propriedades.
    • Verificar e percorrer as propriedades de um objeto
      Teste se uma propriedade existe, liste chaves, valores e pares chave-valor e percorra ou transforme as propriedades de um objeto.
    • Compreender referências, cópias e comparações
      Explique por que objetos são compartilhados por referência, compare objetos corretamente e faça cópias superficiais e profundas.
    • Trabalhar com dados aninhados
      Leia e processe objetos dentro de objetos e vetores de objetos, proteja-se contra partes ausentes com ?. e ?? e escolha uma estrutura adequada aos dados.
  2. Escreva métodos que usam os dados do próprio objeto, explique como a palavra-chave this recebe seu valor em cada tipo de chamada e mantenha o this correto quando um método for passado adiante.
    • Escrever métodos que usam os dados do próprio objeto
      Defina métodos com a sintaxe abreviada, use this para ler e atualizar o objeto e chame métodos corretamente.
    • Explicar como this recebe seu valor
      Determine o valor de this pela forma como uma função é chamada e explique por que funções de seta se comportam de maneira diferente.
    • Preservar this ao passar métodos como funções de retorno
      Reconheça quando um método perde seu objeto e corrija isso com uma função envoltória de seta, bind, call ou apply.
  3. Extraia valores de objetos e vetores com desestruturação e copie, mescle e colete valores com as sintaxes de espalhamento e rest.
    • Desestruturar objetos
      Extraia propriedades de objetos para variáveis, com renomeação, valores padrão, padrões aninhados e parâmetros de função desestruturados.
    • Desestruturar vetores e outros iteráveis
      Extraia valores por posição, ignore posições e defina valores padrão, troque variáveis e desestruture pares chave-valor em laços.
    • Copiar, mesclar e coletar dados com espalhamento e rest
      Use espalhamento para copiar e mesclar objetos e vetores e passar itens de vetor como argumentos, use rest para coletar valores e distinga os dois.
  4. Use Map para coleções de pares chave-valor com chaves de qualquer tipo e Set para coleções de valores únicos, e escolha entre eles e objetos e vetores comuns.
    • Armazenar pares chave-valor em um Map
      Crie e atualize um Map, percorra suas entradas, converta entre Maps e objetos e decida quando um Map é mais adequado que um objeto.
    • Manter valores únicos em um Set
      Crie e atualize um Set, remova duplicatas de vetores e compare coleções com operações de conjuntos.
  5. Leia e escreva o formato de texto JSON, converta valores JavaScript em JSON com JSON.stringify e texto JSON novamente em valores com JSON.parse e trate os casos em que os dois não correspondem.
    • Ler e escrever no formato JSON
      Reconheça JSON válido, explique como ele difere de um literal de objeto JavaScript e identifique erros comuns de sintaxe.
    • Converter valores em texto JSON com JSON.stringify
      Converta objetos e vetores em cadeias de caracteres JSON, formate a saída, escolha quais propriedades incluir e preveja o que será descartado ou alterado.
    • Converter texto JSON em valores com JSON.parse
      Analise JSON com segurança, restaure valores como datas com uma função restauradora, verifique os dados analisados e faça conversões de ida e volta por JSON.

Guia de estudo de Objetos e JSON

5 capítulos

1

Modelar dados com objetos

Um objeto mantém valores relacionados juntos sob nomes, de modo que um registro pode descrever um livro, uma pessoa ou uma leitura. Trabalhar com esses nomes permite alterar um campo, examinar um registro inteiro e organizar listas de registros. Você também acompanhará quais variáveis apontam para o mesmo objeto. Essa distinção importa quando uma alteração aparece em dois lugares, uma cópia contém dados aninhados ou um campo ausente precisa de um valor padrão adequado.

1.1 Criar objetos e trabalhar com suas propriedades

Um objeto agrupa valores relacionados sob nomes. Cada propriedade associa uma chave a um valor. Use um objeto para um registro e um vetor de objetos para uma lista ordenada. Vetores paralelos podem perder seu alinhamento quando apenas um deles é ordenado ou alterado.

Crie e leia um registro
const book = { title: "Dune", pages: 412, available: true };
book.title;    // "Dune"
book["title"]; // "Dune"

Valores de propriedades podem ser vetores, objetos ou funções, além de valores primitivos. Chaves são cadeias de caracteres ou símbolos; estes exemplos usam cadeias de caracteres. Chaves de cadeia de caracteres que são identificadores válidos não precisam de aspas. Chaves que contêm espaços ou hífens precisam de aspas: { "release-year": 1965 }. Chaves numéricas tornam-se cadeias de caracteres, então { 1: "a" } tem a chave "1". Literais de objeto permitem uma vírgula final.

O acesso por ponto usa o nome literal após o ponto. O acesso por colchetes avalia uma expressão:

const field = "pages";
book[field]; // 412
book.field;  // undefined

A segunda expressão procura uma propriedade chamada "field". Colchetes também permitem usar book["release-year"]. Uma propriedade ausente retorna undefined; continuar o acesso por ela, como em book.author.name, lança um TypeError quando author está ausente.

Altere o conteúdo do objeto
book.author = "Frank Herbert";
book.pages = 896;
delete book.available;

A atribuição adiciona uma propriedade ausente ou substitui um valor existente. A exclusão remove a própria propriedade, então "available" in book agora é falso. const mantém a variável vinculada a esse objeto, mas permite alterações em seu conteúdo.

Para const reading = { city: "Nairobi", tempC: 24.5 };, reading.tempC += 1.5; armazena 26. Em seguida, reading.humidity = 61; adiciona um campo. Com const key = "humidity";, reading[key] lê 61. Um nome como tempC deixa visível a unidade da medida.

Use variáveis em um literal
const name = "Lena";
const age = 29;
const person = { name, age };
const lang = "nl";
const greeting = { [lang]: "Hallo" };

A sintaxe abreviada { name, age } significa { name: name, age: age }. Um nome computado avalia a expressão dentro dos colchetes: greeting tem a propriedade "nl". Sem esses colchetes, { lang: "Hallo" } criaria a chave literal "lang".

Principais conclusões

  • Um objeto agrupa valores relacionados em propriedades nomeadas.
  • Use colchetes para uma chave armazenada em uma variável ou que contenha um hífen.
  • Uma atribuição adiciona ou substitui uma propriedade; delete a remove.
  • const fixa a variável, não o conteúdo do objeto.
  • A sintaxe abreviada usa o valor de uma variável; uma chave computada avalia uma expressão.

1.2 Verificar e percorrer as propriedades de um objeto

Verificar se um campo existe é diferente de verificar seu valor. Uma cadeia de caracteres vazia, zero ou false pode ser um valor armazenado perfeitamente válido.

Faça a pergunta certa sobre existência
const item = { stock: 0, note: undefined };
Object.hasOwn(item, "stock"); // true
"note" in item;                // true
Boolean(item.stock);          // false

Object.hasOwn(obj, key) verifica apenas as propriedades próprias do objeto. O operador in também verifica propriedades herdadas: "toString" in {} é true, enquanto Object.hasOwn({}, "toString") é false. Código mais antigo costuma chamar obj.hasOwnProperty(key).

Uma condição como if (item.stock) testa se o valor é avaliado como verdadeiro. Ela não consegue distinguir um campo ausente de um campo presente que contém zero. O mesmo problema se aplica a "", false, null, undefined e NaN. Até mesmo um valor undefined pode pertencer a uma propriedade existente, como acontece com note acima.

Escolha chaves, valores ou pares

Para const scores = { Ana: 82, Ben: 74, Chen: 91 };, estas funções retornam vetores das propriedades próprias enumeráveis com chaves de cadeia de caracteres:

ExpressãoResultado
Object.keys(scores)["Ana", "Ben", "Chen"]
Object.values(scores)[82, 74, 91]
Object.entries(scores)[["Ana", 82], ["Ben", 74], ["Chen", 91]]

O objeto não tem tamanho como um vetor: scores.length é undefined. Object.keys(scores).length conta três propriedades. Para somar as pontuações, reduza os valores com zero como valor inicial. A soma é 247 e a média é aproximadamente 82,33.

Percorra com ambas as partes disponíveis
let bestName;
let bestScore = -Infinity;
for (const [name, score] of Object.entries(scores)) {
  if (score > bestScore) {
    bestName = name;
    bestScore = score;
  }
}

O laço compara 82, 74 e depois 91 com a maior pontuação encontrada até então. Ele termina com "Chen" e 91. O padrão entre colchetes dá nomes às duas partes de cada par.

Um objeto comum não é iterável, então for...of scores lança um TypeError. Object.entries(scores) fornece um vetor iterável. O laço mais antigo for...in produz chaves de cadeia de caracteres e pode incluir propriedades enumeráveis herdadas.

Transforme pares chave-valor novamente em um objeto
const weightsG = { flour: 500, sugar: 250, salt: 5 };
const weightsKg = Object.fromEntries(
  Object.entries(weightsG).map(([item, g]) => [item, g / 1000])
);

entries produz pares, map altera cada valor mantendo sua chave e fromEntries reconstrói o registro. O resultado é { flour: 0.5, sugar: 0.25, salt: 0.005 }; weightsG permanece inalterado.

A ordem das propriedades próprias é definida. Chaves de índice de vetor de "0" até "4294967294" aparecem primeiro em ordem crescente; as demais chaves de cadeia de caracteres seguem a ordem de inserção. Um zero à esquerda, como em "01", impede que uma chave seja um índice de vetor. Assim, Object.keys({ b: 1, 2: "x", a: 2, 1: "y" }) resulta em ["1", "2", "b", "a"]. Use um vetor quando as posições tiverem significado.

Principais conclusões

  • A existência de uma propriedade e o fato de seu valor ser avaliado como verdadeiro respondem a perguntas diferentes.
  • Object.hasOwn verifica propriedades próprias; in também verifica as herdadas.
  • Object.entries fornece pares chave-valor para laços e transformações.
  • Object.fromEntries reconstrói um objeto a partir de pares.
  • Chaves de índice de vetor vêm antes das outras chaves de cadeia de caracteres na ordem das propriedades.
  • Conte chaves próprias enumeráveis de cadeia de caracteres com Object.keys(obj).length.

1.3 Compreender referências, cópias e comparações

Duas variáveis podem se referir a um objeto. Antes de prever uma atualização, decida se o código criou um novo objeto ou copiou uma referência a um objeto existente.

Acompanhe a identidade separadamente dos dados
const p1 = { x: 1 };
const p2 = p1;
p2.x = 99;
p1.x;       // 99
p1 === p2;  // true

A atribuição copiou a referência. Ambos os nomes acessam a mesma propriedade. A atribuição de valores primitivos funciona de modo diferente: após let a = 5; let b = a; b = 6;, a continua sendo 5.

Objetos são comparados por identidade tanto com === quanto com ==. Dois literais criam objetos separados mesmo quando todos os campos coincidem: ({ x: 1 } === { x: 1 }) é false. Para comparar seus dados, compare as propriedades relevantes. Ter a mesma aparência quando impressos não é uma verificação de identidade.

Passar um objeto para uma função também copia sua referência. Uma função que executa order.status = "shipped"; altera o objeto de quem a chamou. Retornar { ...order, status: "shipped" } cria um novo registro no nível superior.

Distinga const, congelamento e cópia

const cart = { items: 2 }; permite cart.items = 3;, mas reatribuir com cart = {}; lança um TypeError. Object.freeze(cart) impede alterações em suas propriedades próprias. Em modo estrito, tentativas de adicioná-las, removê-las ou sobrescrevê-las lançam um TypeError.

O congelamento é superficial. Se um registro congelado contém outro objeto, os campos desse objeto aninhado ainda podem mudar. Um contêiner congelado e uma estrutura completamente imutável são coisas diferentes.

Acompanhe uma cópia superficial
const settings = { theme: "dark", font: { size: 14 } };
const copy = { ...settings };
copy.theme = "light";
copy.font.size = 18;

O espalhamento cria um novo objeto externo. Seu valor theme é copiado, então alterar copy.theme mantém settings.theme como "dark". Seu valor font é uma referência, copiada para ambos os registros. Atualizar copy.font.size também faz settings.font.size ser igual a 18.

Object.assign({}, settings) também faz uma cópia superficial. Uma cópia superficial separa o registro externo, mantendo a identidade dos objetos e vetores aninhados.

Copie dados aninhados quando precisarem ser independentes
const deep = structuredClone(settings);
deep.font.size = 22;
settings.font.size; // 18

structuredClone copia objetos e vetores aninhados, além de valores compatíveis como Map, Set e Date. Ele também trata referências circulares. O novo font aninhado pode mudar independentemente. Funções não podem ser clonadas dessa maneira: um objeto que contém um método causa um DataCloneError.

Uma conversão de ida e volta por JSON, JSON.parse(JSON.stringify(obj)), copia apenas dados compatíveis com JSON. Ela descarta propriedades de objeto que contêm undefined ou funções, transforma datas em cadeias de caracteres e perde entradas de Map e Set, a menos que você os converta. Escolha uma clonagem para obter dados JavaScript compatíveis e independentes e escolha JSON quando quiser criar uma representação em texto.

Principais conclusões

  • Atribuições e chamadas de função copiam referências a objetos.
  • Objetos são comparados por identidade, mesmo quando seus campos coincidem.
  • Uma cópia superficial compartilha objetos aninhados.
  • Object.freeze impede alterações em propriedades próprias, mas é superficial.
  • structuredClone copia dados aninhados compatíveis e rejeita funções.

1.4 Trabalhar com dados aninhados

Dados aninhados combinam registros e listas. Leia um caminho uma etapa por vez, verificando se cada etapa chega a um objeto, um vetor ou um valor final.

Leia e processe uma lista dentro de um registro
const order = {
  id: 1042,
  customer: { name: "Sara", city: "Lisbon" },
  items: [
    { product: "Tea", qty: 2, unitPrice: 4.5 },
    { product: "Mug", qty: 1, unitPrice: 9 }
  ]
};

order.customer.city lê "Lisbon". order.items[1].product primeiro seleciona o vetor de itens, depois seu segundo registro e então "Mug". order.items.length é 2.

Os métodos de vetor que você já conhece funcionam com propriedades de registros. map(item => item.product) produz nomes de produtos. filter(item => item.qty > 1) mantém o item de chá. find(item => item.product === "Mug") retorna o registro existente da caneca, então alterar o registro retornado altera o item no pedido.

Para calcular o total, use order.items.reduce((sum, item) => sum + item.qty * item.unitPrice, 0). O primeiro item adiciona 9; o segundo adiciona mais 9, produzindo 18. Calcular um total quando necessário impede que um total armazenado separadamente fique desatualizado quando os itens mudarem.

Leia dados opcionais com uma alternativa de contingência
order.shipping?.date;                 // undefined
order.customer?.city ?? "unknown";    // "Lisbon"

O encadeamento opcional, ?., para quando o valor imediatamente à sua esquerda é null ou undefined. Um acesso direto order.shipping.date lançaria um TypeError. Use uma verificação em cada parte opcional de um caminho mais longo. O acesso por colchetes e as chamadas também aceitam esse recurso: order.items?.[0] e order.print?.().

O encadeamento opcional é para valores que podem estar ausentes. Campos obrigatórios ainda precisam de verificações ou erros que revelem um registro inválido. Ele não pode aparecer à esquerda de uma atribuição: order.shipping?.date = "2026-05-01" é um erro de sintaxe.

O operador de coalescência nula, ??, usa seu lado direito apenas para null ou undefined. Ele preserva zero, false e "". Para const qty = 0;, qty ?? 1 continua sendo zero, enquanto qty || 1 se torna 1 porque || substitui todo valor avaliado como falso.

Escolha uma estrutura útil

Um vetor de registros é adequado para listagem, filtragem e ordenação. Um objeto indexado por ID permite consulta direta: usersById["u23"].name. Um Map é útil quando chaves de consulta são adicionadas e removidas com frequência.

O JavaScript mais recente oferece Object.groupBy, amplamente disponível desde 2024:

const tasks = [
  { title: "Book flights", status: "done" },
  { title: "Pack", status: "todo" },
  { title: "Renew passport", status: "done" }
];
const grouped = Object.groupBy(tasks, task => task.status);

grouped.done contém dois registros e grouped.todo contém um. O resultado não tem protótipo, então não tem o método herdado toString. Uma alternativa mais antiga constrói os vetores explicitamente para essas chaves de status:

const groupedOlder = tasks.reduce((groups, task) => {
  if (!Object.hasOwn(groups, task.status)) {
    groups[task.status] = [];
  }
  groups[task.status].push(task);
  return groups;
}, {});

O primeiro registro de cada grupo cria seu vetor. Os registros seguintes são adicionados a esse mesmo vetor. Esse acumulador é um objeto comum; o resultado do método mais recente não tem protótipo. Use nomes e tipos de valor consistentes entre registros; nomes como distanceKm e tempC também mantêm as unidades visíveis.

Principais conclusões

  • Leia um caminho aninhado do objeto externo até o valor necessário.
  • find retorna o registro existente, não uma cópia.
  • ?. para em uma parte nula ou indefinida; ?? fornece uma alternativa para um valor nulo ou indefinido.
  • Use um vetor para uma lista ordenada e dados indexados por chave para consulta direta.
  • Object.groupBy agrupa registros em vetores sob chaves.
  • Nomes de campos, tipos e unidades consistentes tornam os registros mais fáceis de processar.
2

Dar comportamento aos objetos com métodos e this

Métodos permitem que um objeto combine seus dados com ações que os utilizam. A pequena palavra this conecta uma ação a um objeto, mas seu valor depende de como a função é executada. Você acompanhará chamadas comuns de método, métodos emprestados e funções de retorno e, em seguida, escolherá uma função envoltória ou vinculada quando uma ação precisar manter seu objeto. Os exemplos são executados como módulos, portanto o modo estrito se aplica, salvo quando um exemplo usar explicitamente código não estrito.

2.1 Escrever métodos que usam os dados do próprio objeto

Um método é uma propriedade cujo valor é uma função chamada por meio de um objeto. Ele permite que uma ação use os dados atuais do registro.

Escreva um método com this
const counter = {
  count: 0,
  increment() {
    this.count += 1;
    return this.count;
  }
};
counter.increment(); // 1
counter.increment(); // 2

A sintaxe abreviada increment() { ... } define uma propriedade cujo valor é uma função comum. Em counter.increment(), o objeto receptor counter se torna this. Cada chamada lê a contagem armazenada, adiciona um e retorna o novo número.

Um count isolado seleciona uma variável, não a propriedade. Sem uma variável correspondente, count += 1 lança um ReferenceError. Use this.count para acessar o campo do objeto receptor.

Leia uma função ou execute-a

counter.increment lê um valor do tipo "function". Os parênteses em counter.increment() executam a função e fornecem seu valor de retorno. Ao passar uma ação para uso posterior, o código que a recebe precisa da função, não do resultado de executá-la agora.

Métodos nativos também usam essa forma de chamada: Math.max(3, 7) retorna 7 e "abc".toUpperCase() retorna "ABC".

Reutilize uma ação
function describe() {
  return this.name + " (" + this.year + ")";
}
const film = { name: "Up", year: 2009, describe };
const song = { name: "Hello", year: 2015, describe };

film.describe() retorna "Up (2009)"; song.describe() retorna "Hello (2015)". Usar this permite que a mesma função leia qualquer um dos objetos receptores. Fixar film.name no código a vincularia à variável film.

Retorne o objeto receptor para outra ação
const playlist = {
  tracks: [],
  add(title) { this.tracks.push(title); return this; },
  count() { return this.tracks.length; }
};
playlist.add("Rain").add("Waves").count(); // 2

Cada chamada de add retorna a lista de reprodução, permitindo procurar o próximo método nesse objeto. Retornar um número de add quebraria a cadeia, pois o próximo add seria procurado nesse número.

A conversão comum para JSON omite métodos: converter { name: "Kit", hi() { return 1; } } em texto escreve apenas name. A análise sintática não consegue restaurar código omitido. Registros para salvar ou trocar frequentemente mantêm dados simples e usam funções de processamento separadas.

Principais conclusões

  • Um método é uma propriedade cujo valor é uma função chamada por meio de um objeto.
  • Em obj.method(), um método comum usa obj como this.
  • Uma função como valor e o resultado de chamá-la são valores diferentes.
  • Retornar this pode permitir uma chamada de método em seguida.
  • A conversão comum para JSON omite propriedades cujo valor é uma função.

2.2 Explicar como this recebe seu valor

Para uma função comum, a chamada determina this. Armazenar uma função em um objeto não a vincula permanentemente a esse objeto.

Acompanhe o objeto receptor na chamada
const a = { n: "A", who() { return this.n; } };
const b = { n: "B" };
b.who = a.who;
a.who(); // "A"
b.who(); // "B"

Ambas as propriedades contêm a mesma função. O objeto receptor antes do ponto é diferente, então os resultados são diferentes. O local original da função não determina qual objeto ela lê.

Para uma chamada simples, f(), o modo estrito fornece undefined como this. Módulos JavaScript sempre são executados em modo estrito; um script ou função também pode começar com "use strict";. Uma função comum não estrita chamada de forma simples usa o objeto global, globalThis. Em um navegador, esse objeto global é window.

Reconheça o contexto ao redor de uma função de seta

Uma função de seta não tem this próprio. Ela mantém o this do código ao redor do local onde foi criada. Um literal de objeto não cria um novo contexto de this.

// At the top level of a module:
const user = {
  name: "Ida",
  hi: () => "Hi, " + this.name
};

Chamar user.hi() lança um TypeError: a função de seta capturou o this do nível superior do módulo, que é undefined. Alterar a chamada para que pareça um método não pode dar um novo objeto receptor à função de seta. No nível superior de um script clássico, o this ao redor é o objeto global.

Use um método comum quando a ação precisar do objeto que faz a chamada. Use uma função de seta dentro desse método quando uma função de retorno precisar manter o contexto do método:

const group = {
  title: "Team",
  members: ["Ana", "Ben"],
  list() {
    return this.members.map(m => this.title + ": " + m);
  }
};
group.list(); // ["Team: Ana", "Team: Ben"]

list recebe group de sua chamada de método. A função de seta é criada dentro desse método em execução e mantém o mesmo this. Uma função de retorno comum em modo estrito, sem um objeto receptor fornecido, receberia undefined, então this.title falharia nela.

Use uma ordem de decisão

Quando encontrar uma chamada, primeiro identifique a função que está sendo chamada:

  1. Uma função de seta mantém o this ao seu redor; call, apply e bind não podem substituí-lo.
  2. Uma função comum vinculada mantém seu this vinculado, mesmo com call ou apply.
  3. Uma função comum não vinculada chamada com call ou apply usa o this fornecido.
  4. Uma chamada comum obj.method() usa obj.
  5. Uma chamada simples de função comum usa undefined em modo estrito ou o objeto global em modo não estrito.

Funções de retorno podem receber um objeto receptor de quem as chama. Por exemplo, um ouvinte de evento DOM comum registrado com addEventListener recebe como this o elemento no qual está registrado. Veja como o código que recebe uma função de retorno a chama antes de supor que se trata de uma chamada simples.

Principais conclusões

  • Uma função comum recebe this de sua chamada, então emprestar um método muda seu objeto receptor.
  • Uma chamada simples em modo estrito usa undefined como this.
  • Uma função de seta mantém o this ao redor do local onde foi criada.
  • Um objeto receptor vinculado tem precedência sobre chamadas posteriores com call ou apply.
  • Uma função de seta dentro de um método comum pode manter o this desse método.

2.3 Preservar this ao passar métodos como funções de retorno

Extrair um método de seu objeto preserva a função, mas perde a expressão de chamada original. Uma função de retorno deve ser chamada de uma forma que forneça o objeto de que ela precisa.

Diagnostique um método desvinculado
const counter = {
  count: 0,
  increment() {
    this.count += 1;
    return this.count;
  }
};
const inc = counter.increment;
inc(); // TypeError in strict mode

inc() é uma chamada simples, então this é undefined. A leitura de this.count falha antes que um incremento possa ocorrer. Em código não estrito, uma chamada simples usa o objeto global e pode escrever em um count global; ela não acessa o contador.

O mesmo problema aparece em funções de retorno de vetores. [1, 2].map(counter.increment) fornece uma função a map sem seu objeto receptor original. Os valores do vetor passados como argumentos não fornecem this.

Envolva a chamada do método
const results = [1, 2].map(() => counter.increment());
// results is [1, 2]; counter.count is 2

A função de retorno é uma função de seta que faz uma chamada normal de counter.increment(). Essa chamada tem um objeto receptor. A função envoltória ignora deliberadamente os valores passados por map; cada chamada apenas incrementa uma vez. Essa forma é conveniente quando a função de retorno é necessária em um único uso.

Vincule uma função reutilizável

Começando com um novo contador em zero:

const boundInc = counter.increment.bind(counter);
const results = [1, 2].map(boundInc);
// results is [1, 2]; counter.count is 2

bind retorna uma nova função; ele ainda não chama o método. A nova função mantém counter como seu objeto receptor. Vinculá-la novamente a outro objeto não pode substituir esse receptor. Cada chamada de bind cria uma função distinta, então salve o resultado quando o código precisar reconhecer exatamente a mesma função de retorno mais tarde.

A vinculação também pode fixar argumentos iniciais. function multiply(a, b) { return a * b; } seguido de const double = multiply.bind(null, 2); faz double(21) retornar 42. null ocupa a posição do objeto receptor porque essa função não usa this; 2 ocupa seu primeiro parâmetro comum.

Execute uma vez com call ou apply
function describe(unit) {
  return this.value + " " + unit;
}
describe.call({ value: 12 }, "kg");    // "12 kg"
describe.apply({ value: 12 }, ["kg"]); // "12 kg"

Ambas as formas executam imediatamente com o objeto receptor escolhido. call fornece os argumentos separadamente; apply os fornece em um vetor. O contexto de uma função de seta é fixado pelo que a envolve, então esses métodos não podem substituir seu this.

Passar counter.increment() como função de retorno executa o método imediatamente e passa o número retornado. Esse não é o tipo de função de que map precisa. Em um registro de evento como button.addEventListener("click", counter.increment()), o contador muda imediatamente e o ouvinte numérico causa um TypeError. Passe uma função como valor, uma função envoltória de seta ou uma função vinculada armazenada.

Principais conclusões

  • Desvincular um método remove seu objeto receptor original.
  • Uma função envoltória de seta pode fazer a chamada de método necessária mais tarde.
  • bind cria uma função com um objeto receptor fixo e argumentos iniciais opcionais.
  • call e apply executam imediatamente; seus formatos de argumentos são diferentes.
  • Argumentos usados como funções de retorno devem ser funções, não o resultado numérico da execução de um método.
3

Extrair e combinar dados com desestruturação, espalhamento e rest

A desestruturação dá nomes a partes selecionadas de um objeto ou de uma coleção ordenada. O espalhamento constrói valores a partir de partes existentes, enquanto rest reúne as partes restantes. Essas formas frequentemente aparecem juntas em funções que recebem opções ou retornam registros atualizados. Observar sua posição com atenção permite prever quais variáveis existem, quais valores padrão se aplicam e se dados aninhados são compartilhados com o original.

3.1 Desestruturar objetos

A desestruturação de objetos lê campos nomeados para variáveis locais. Ela seleciona valores sem copiar todo o registro de origem.

Faça a correspondência e renomeie
const book = { title: "Dune", pages: 412 };
const { pages, title: bookTitle, rating: stars = 0 } = book;

A correspondência usa nomes de propriedades, não sua ordem. Isso declara pages como 412, bookTitle como "Dune" e stars como 0. Não declara variáveis title ou rating: o nome após os dois-pontos é a variável local de destino.

Um campo ausente fornece undefined. Um valor padrão substitui apenas undefined, preservando null, zero, false e cadeias de caracteres vazias. const { a = 5 } = { a: null }; deixa, portanto, a como null.

Acompanhe campos aninhados
const data = {
  location: { name: "Oslo" },
  current: { tempC: -3, windKph: 18 }
};
const {
  location: { name },
  current: { tempC, windKph: wind }
} = data;

As variáveis declaradas são name, tempC e wind, com os valores "Oslo", -3 e 18. Os nomes externos location e current selecionam caminhos; eles não se tornam variáveis.

Um objeto externo ausente faz uma leitura aninhada falhar. const { shipping: { date } } = {}; lança TypeError. Forneça um valor padrão externo quando esse campo puder ser undefined:

const { shipping: { date } = {} } = {};
// date is undefined

Isso não substitui shipping quando seu valor é null. Desestruturar null ou undefined diretamente também lança um erro, então a origem deve ser utilizável antes do início da extração.

Receba opções nomeadas
function formatUser({ name, age = "unknown" }) {
  return name + ", " + age;
}

formatUser({ name: "Mo" }) retorna "Mo, unknown". Reordenar os campos em { age: 40, name: "Ines" } ainda retorna "Ines, 40". Chamar formatUser sem argumento falha porque não há objeto para desestruturar. Um valor padrão para todo o parâmetro permite essa chamada:

function greet({ name = "guest" } = {}) {
  return "Hi, " + name;
}
greet(); // "Hi, guest"

O valor padrão externo trata um argumento omitido; o valor padrão interno trata um nome ausente. Passar null ainda causa uma falha. Para atribuir valores a variáveis existentes, envolva uma instrução com padrão de objeto entre parênteses: let x, y; ({ x, y } = { x: 4, y: 7 });. Caso contrário, as chaves iniciais são interpretadas como um bloco de instruções.

Principais conclusões

  • Padrões de objeto fazem a correspondência de propriedades pelo nome.
  • Os dois-pontos renomeiam a variável; eles não alteram a chave de origem.
  • Valores padrão substituem undefined, inclusive em propriedades ausentes, e preservam null.
  • Padrões aninhados precisam de um objeto utilizável em cada nível.
  • Um valor padrão para todo o parâmetro e um valor padrão para uma propriedade tratam valores ausentes diferentes.
  • Parênteses permitem que um padrão de objeto atribua valores a variáveis existentes.

3.2 Desestruturar vetores e outros iteráveis

A desestruturação de vetores lê valores por posição de um iterável. As vírgulas controlam quais valores são selecionados; os nomes das variáveis não escolhem posições.

Selecione ou ignore posições
const medals = ["gold", "silver", "bronze"];
const [first, second] = medals;
const [, , third] = medals;

As variáveis recebem "gold", "silver" e "bronze". Posições vazias consomem valores sem declarar variáveis. Um nome além dos valores disponíveis recebe undefined. Valores padrão substituem apenas undefined:

const [p, q = 10] = [1]; // p is 1; q is 10
const [r = 10] = [null]; // r is null
Reúna os valores restantes
const [head, ...tail] = [1, 2, 3, 4];
// head is 1; tail is [2, 3, 4]

O elemento rest final cria um novo vetor, vazio quando nada resta. Ele deve ser o último. Quaisquer valores que sejam objetos dentro desse vetor mantêm suas identidades; coletá-los não os clona profundamente.

Leia um par retornado ou troque variáveis
function minMax(nums) {
  return [Math.min(...nums), Math.max(...nums)];
}
const [lo, hi] = minMax([4, 9, 1]);
// lo is 1; hi is 9

Quem chama segue a ordem definida pela função que retorna os valores. Para muitos campos de resultado, propriedades nomeadas em objetos evitam ter de lembrar posições.

Com let x = 1, y = 2;, [x, y] = [y, x]; troca os valores das variáveis. O vetor à direita é avaliado como [2, 1] antes de qualquer atribuição, preservando os dois valores antigos sem uma variável temporária.

Extraia valores de outros iteráveis

Cadeias de caracteres e Sets também podem ser desestruturados: const [initial] = "Zoe"; resulta em "Z". Sets fornecem valores na ordem de inserção. Entradas de Map são pares ordenados:

const distances = new Map([["park", 2], ["lake", 5]]);
for (const [place, distanceKm] of distances) {
  console.log(place, distanceKm);
}

O laço recebe um par e, em seguida, o padrão separa sua chave e seu valor. Object.entries fornece a mesma estrutura de par.

Um objeto comum não é iterável, então const [name] = { name: "Ana" }; lança TypeError. Use chaves para selecionar seu campo nomeado: const { name } = { name: "Ana" };. Colchetes exigem uma sequência de valores; chaves selecionam propriedades pelo nome.

Principais conclusões

  • Padrões de vetor fazem a correspondência por posição, e posições vazias ignoram valores.
  • Uma posição ausente resulta em undefined, a menos que um valor padrão o substitua.
  • Um elemento rest final coleta os valores restantes em um novo vetor.
  • Padrões de vetor também funcionam em cadeias de caracteres, Sets e entradas de Map.

3.3 Copiar, mesclar e coletar dados com espalhamento e rest

Os três pontos, ..., têm duas funções relacionadas. O espalhamento expande dados existentes em um valor ou uma chamada. Rest reúne valores em uma variável declarada por um padrão ou parâmetro.

Mescle na ordem de prioridade
const defaults = { lang: "en", units: "metric", alerts: true };
const user = { lang: "pt", alerts: false };
const options = { ...defaults, ...user };
// { lang: "pt", units: "metric", alerts: false }

O espalhamento de objetos copia propriedades próprias enumeráveis. Quando uma chave aparece novamente, prevalece o valor posterior. Colocar user antes de defaults sobrescreveria as configurações do usuário. Espalhar null ou undefined em um objeto não adiciona nada.

Cópias por espalhamento são superficiais. Se um registro aninhado mudar, copie esse nível também:

const settings = { theme: "dark", font: { size: 14, family: "serif" } };
const next = {
  ...settings,
  font: { ...settings.font, size: 18 }
};

O espalhamento externo preserva theme. O interno preserva family enquanto substitui size. settings.font.size permanece 14 porque o registro aninhado alterado é novo.

Substitua um registro em uma lista
const todos = [{ id: 1, done: false }, { id: 2, done: false }];
const updated = todos.map(t =>
  t.id === 2 ? { ...t, done: true } : t
);

map cria um novo vetor. O item correspondente se torna um novo objeto, então updated[1].done é true enquanto todos[1].done continua sendo false. O primeiro item, inalterado, é reutilizado: updated[0] === todos[0] é true. Atualizações independentes não exigem copiar registros inalterados.

Expanda valores iteráveis

Em um literal de vetor ou chamada de função, o espalhamento extrai valores de um iterável. [...a, ...b] junta seus valores em um novo vetor. Math.max(...[4, 9, 1]) passa três argumentos e retorna 9. Um objeto comum não pode ser expandido em um vetor: [...{ a: 1 }] lança um TypeError. O espalhamento de objetos e o espalhamento de iteráveis usam regras diferentes para determinar o que leem.

Reúna argumentos ou propriedades restantes
function total(...nums) {
  return nums.reduce((sum, n) => sum + n, 0);
}
total(2, 3, 5); // 10
total();        // 0

Um parâmetro rest recebe um vetor verdadeiro, mesmo quando não recebe valores. Ele deve ser o último parâmetro, e só pode haver um. O antigo objeto arguments não é um vetor verdadeiro. Funções de seta não têm arguments próprio, embora possam ler a vinculação de uma função comum que as envolve.

A sintaxe rest de objetos coleta propriedades próprias enumeráveis que ainda não foram selecionadas:

const userRecord = { id: 8, name: "Rae", password: "x9!k" };
const { password, ...publicUser } = userRecord;
// publicUser is { id: 8, name: "Rae" }

Isso cria um novo registro e deixa a origem inalterada. A propriedade rest deve ser a última. Observe a posição para distinguir as funções: três pontos em um literal ou chamada espalham valores para fora; três pontos em uma lista de parâmetros ou em um destino de desestruturação reúnem valores.

Principais conclusões

  • Propriedades posteriores prevalecem quando espalhamentos de objetos têm chaves em comum.
  • Copie cada nível aninhado que precisa mudar de forma independente.
  • O espalhamento em vetores e chamadas precisa de um iterável.
  • Rest coleta argumentos, itens ou propriedades restantes e deve vir por último.
  • Uma atualização com map pode copiar um registro alterado enquanto reutiliza registros inalterados.
  • Parâmetros rest são vetores verdadeiros; o antigo objeto arguments não é.
4

Armazenar coleções com Map e Set

Algumas coleções precisam de chaves que sejam objetos ou números, e outras precisam manter cada valor apenas uma vez. Map e Set expressam essas necessidades diretamente. Você criará entradas, testará a pertinência, acompanhará a ordem de inserção e converterá coleções em vetores ou objetos quando outra operação precisar dessa estrutura. A igualdade continua sendo importante: dois registros com campos iguais podem continuar sendo dois valores separados em qualquer uma das coleções.

4.1 Armazenar pares chave-valor em um Map

Um Map armazena associações entre chaves e valores. Diferentemente das chaves de cadeia de caracteres de um objeto comum, uma chave de Map pode ser um número, um objeto ou outro valor sem ser convertida em uma cadeia de caracteres.

Crie e mantenha entradas
const stock = new Map();
stock.set("apples", 12).set("pears", 7);
stock.get("apples"); // 12
stock.has("kiwis");  // false
stock.size;           // 2

set adiciona uma entrada ou substitui seu valor e retorna o Map para encadeamento. get retorna undefined para uma chave ausente; use has para distinguir isso de uma entrada que armazena undefined. delete(key) retorna se removeu uma entrada, e clear() esvazia a coleção.

A notação de colchetes usa uma área de armazenamento diferente: stock["plums"] = 5; adiciona uma propriedade comum ao objeto Map. Ela não cria uma entrada visível para get, has ou size. Use os métodos de Map para entradas.

Mantenha tipos e identidades das chaves

m.set(1, "number"); m.set("1", "text"); cria duas entradas. As chaves 1 e "1" de um objeto comum se refeririam a uma única propriedade. Chaves de Map são comparadas como em ===, exceto que NaN corresponde a si mesmo e zeros com sinais diferentes compartilham uma chave.

const person = { id: 1 };
const notes = new Map([[person, "ready"]]);
notes.get(person);      // "ready"
notes.get({ id: 1 });   // undefined

A segunda consulta cria um novo objeto. Campos iguais não fazem dele a mesma chave. Guarde e reutilize a referência ao objeto original quando usar um objeto como chave.

Percorra e converta pares
for (const [name, count] of stock) {
  console.log(name, count);
}

Um Map fornece pares [key, value] na ordem da primeira inserção. Substituir um valor não muda a posição de sua chave. keys(), values() e entries() retornam iteradores que você pode percorrer ou espalhar em vetores. forEach passa à sua função de retorno primeiro o valor e depois a chave.

new Map(Object.entries(obj)) transforma as entradas de um registro em um Map. Object.fromEntries(map) cria um objeto; use-o quando as chaves forem cadeias de caracteres, pois chaves de objeto não conseguem preservar todos os tipos de chave de Map. [...map] cria um vetor de pares, útil para salvar as entradas de um Map como JSON.

Conte chaves que mudam
const words = "the cat saw the dog and the bird".split(" ");
const counts = new Map();
for (const word of words) {
  counts.set(word, (counts.get(word) ?? 0) + 1);
}

A primeira ocorrência começa em zero e depois soma um. Ocorrências posteriores leem e aumentam a contagem armazenada. counts.get("the") é 3 e counts.size é 6: o tamanho conta palavras distintas, não todas as oito ocorrências.

Escolha um objeto comum para um registro com campos conhecidos, especialmente dados compatíveis com JSON. Escolha um Map para chaves que mudam, verificações frequentes de tamanho ou chaves cujos tipos precisam ser preservados. O Map.groupBy mais recente preserva os tipos das chaves de grupo:

const owner = { name: "Ari" };
const jobs = [{ owner, done: false }, { owner, done: true }];
const byOwner = Map.groupBy(jobs, job => job.owner);
byOwner.get(owner).length; // 2

Em código mais antigo, percorra jobs em um laço. Para cada owner, use has e set para criar um vetor de grupo uma vez e depois get(owner).push(job) para adicionar o registro. Manter owner como chave de objeto distingue responsáveis diferentes mesmo quando seus campos de nome são iguais. Um WeakMap pode associar metadados a objetos sem manter vivos objetos usados como chaves que, de outro modo, seriam inalcançáveis. Ele não permite iteração nem tem tamanho. WeakMaps modernos também aceitam símbolos não registrados como chaves.

Principais conclusões

  • Chaves de Map preservam seus tipos e comparam objetos por identidade.
  • Use set, get, has e delete para entradas, não a notação de colchetes.
  • size conta entradas e a iteração segue a ordem de inserção das chaves.
  • Maps são convertidos por meio de pares chave-valor.
  • Um WeakMap pode manter metadados de objetos sem manter vivos os objetos usados como chaves.
  • Map.groupBy preserva os tipos das chaves de grupo em uma API de agrupamento mais recente.

4.2 Manter valores únicos em um Set

Um Set armazena valores únicos. Suas principais questões são se um valor está presente e como duas coleções se sobrepõem.

Adicione e teste valores
const tags = new Set(["js", "css", "js"]);
tags.size;       // 2
tags.add("html");
tags.has("css"); // true

Adicionar um valor existente não altera nada. add retorna o Set para encadeamento. delete(value) retorna se o valor foi removido, enquanto clear() remove todos os valores. O construtor recebe um iterável: use new Set([1, 2, 3]). new Set(1, 2, 3) lança um TypeError porque sua primeira entrada não é iterável. Uma cadeia de caracteres é iterável, então new Set("hello") contém "h", "e", "l" e "o".

Um Set não tem posições indexadas. tags[0] é undefined. Percorra-o com for...of, chame forEach ou converta-o em um vetor para operações como map e filter. A iteração segue a ordem de inserção; remover um valor e adicioná-lo novamente o coloca no fim.

Remova duplicatas sem ordenar
const unique = [...new Set([3, 1, 3, 2, 1])];
// [3, 1, 2]

O Set mantém a primeira ocorrência de cada valor. O espalhamento fornece esses valores em um vetor. Array.from(set) faz a mesma conversão.

Os valores são comparados como em ===, exceto que NaN corresponde a si mesmo; zeros com sinais diferentes contam como um valor. Valores que são objetos são comparados por identidade: new Set([{ id: 1 }, { id: 1 }]).size é 2. Para manter um registro por ID, construa um Map indexado por esse ID e depois leia seus valores. Registros posteriores com o mesmo ID substituem os anteriores, porque set atualiza uma entrada existente.

Para testes de pertinência repetidos em coleções grandes, um Set evita a busca um a um feita por includes em um vetor. Use-o quando a presença for mais importante que a posição.

Compare duas coleções

Métodos mais recentes de Set estão disponíveis nos principais navegadores desde 2024. Com a contendo 1, 2, 3, 4 e b contendo 3, 4, 5:

OperaçãoSignificadoValores resultantes
a.union(b)Em qualquer uma das coleções1, 2, 3, 4, 5
a.intersection(b)Em ambas3, 4
a.difference(b)Em a, mas não em b1, 2
a.symmetricDifference(b)Em exatamente uma1, 2, 5

Essas operações retornam novos Sets. isSubsetOf verifica se cada valor está na outra coleção. isSupersetOf verifica a relação inversa de inclusão. isDisjointFrom verifica se as coleções não compartilham valores. Os três retornam booleanos. Por exemplo, new Set([3, 4]).isSubsetOf(a) é true. A diferença tem uma direção: os valores em b, mas não em a, seriam apenas 5.

Em um ambiente mais antigo, uma interseção pode ser escrita como new Set([...a].filter(x => b.has(x))).

A chamada comum JSON.stringify(set) produz "{}", perdendo os valores armazenados. Converta para um vetor antes de escrever JSON e depois use new Set(parsedArray) ao ler. Um WeakSet pode marcar objetos como processados sem manter vivos objetos que, de outro modo, seriam inalcançáveis. Ele não pode ser percorrido. WeakSets modernos também aceitam símbolos não registrados.

Principais conclusões

  • Um Set armazena cada valor distinto uma vez e testa sua presença com has.
  • Converta um Set em vetor para usar índices ou métodos de vetor.
  • Valores que são objetos permanecem distintos, a menos que suas referências correspondam.
  • União, interseção, diferença e diferença simétrica respondem a perguntas diferentes sobre pertinência.
  • A diferença depende de qual Set vem primeiro.
  • Converta valores de Set em um vetor antes de escrever JSON.
  • WeakSet pode marcar objetos sem mantê-los vivos.
5

Converter dados para JSON e de JSON

JSON transporta dados estruturados como texto. Converter entre esse texto e valores JavaScript em uso só é útil quando você sabe quais informações sobrevivem à conversão. Você reconhecerá JSON válido, controlará como os valores são escritos e tratará entradas malformadas ao lê-las. Uma análise sintática bem-sucedida também exige uma verificação da estrutura dos dados antes que o programa dependa de seus campos; um texto válido por si só não garante os dados esperados.

5.1 Ler e escrever no formato JSON

JSON, abreviação de JavaScript Object Notation, é um formato de texto independente de linguagem para dados estruturados. Um objeto é um valor JavaScript em uso; JSON é texto que pode descrever esse valor.

Reconheça os seis tipos de valor

JSON aceita objetos, vetores, cadeias de caracteres, números, booleanos e null. Qualquer um deles pode ser o valor de nível superior. O texto 42 é JSON válido mesmo sem chaves. JSON não tem representação para funções, undefined, datas como um tipo distinto, Map, Set, NaN ou Infinity.

{
  "name": "Amara",
  "age": 34,
  "languages": ["en", "yo"],
  "address": null,
  "member": true
}

As mesmas ideias estruturais aparecem em literais JavaScript, mas a forma permitida é mais restrita. JSON é usado em configurações e na troca de dados. JSON trocado entre sistemas usa a codificação UTF-8 e o tipo de mídia application/json; arquivos JSON usam a extensão .json.

Aplique as regras de sintaxe

Toda chave de objeto deve ser uma cadeia de caracteres entre aspas duplas. Cadeias de caracteres também exigem aspas duplas. Vírgulas separam propriedades ou itens de vetor, mas nenhuma vírgula pode vir após o último. Comentários são proibidos. Espaços em branco entre valores e sinais de pontuação são permitidos.

TextoPor que falha
{name: "Amara"}A chave não tem aspas duplas.
{'name': 'Amara'}Aspas simples não delimitam cadeias de caracteres JSON.
{"a": 1,}Não há propriedade após a vírgula final.
{"a": undefined}Undefined não é um valor JSON.

Números usam notação decimal. 1.5e3, -0.25 e 0 são válidos. 07, +1 e 0x1F são inválidos porque JSON proíbe zeros à esquerda, um sinal de adição inicial e notação hexadecimal.

Use sequências de escape dentro de cadeias de caracteres

Use \" para aspas duplas, \\ para uma barra invertida, \n para uma nova linha e \t para uma tabulação dentro de uma cadeia JSON. Uma quebra de linha literal não pode aparecer dentro de uma cadeia JSON. Deixe JSON.stringify gerar sequências de escape a partir dos valores reais das cadeias de caracteres, para que aspas internas não invalidem a saída.

Uma sequência de escape Unicode consiste em uma barra invertida, a letra u e quatro dígitos hexadecimais para uma unidade de código UTF-16. Por exemplo, \u00e9 representa é. Um caractere fora desse intervalo pode precisar de duas dessas sequências; ele também pode ser escrito diretamente na cadeia. As aspas ao redor de um texto JSON no código-fonte JavaScript são uma camada separada das aspas dentro do próprio JSON.

Preserve identificadores e evite chaves duplicadas

Números JavaScript preservam todos os inteiros no intervalo seguro de -9007199254740991 até 9007199254740991. Fora desse intervalo, alguns inteiros permanecem exatos e outros são arredondados. Analisar '{"id":9007199254740993}' fornece um valor id de 9007199254740992. Armazene identificadores longos como cadeias de caracteres JSON quando seus dígitos exatos forem importantes.

Chaves devem ser únicas dentro de cada objeto JSON. O JSON.parse do JavaScript mantém a última ocorrência quando uma chave se repete: analisar '{"a":1,"a":2}' produz { a: 2 }. Não é possível recuperar propriedades distintas desse nome repetido.

Principais conclusões

  • JSON é texto com seis tipos de valor, incluindo valores primitivos no nível superior.
  • Chaves e cadeias de caracteres precisam de aspas duplas; comentários e vírgulas finais são inválidos.
  • Números JSON não aceitam notação hexadecimal, sinais de adição iniciais nem zeros à esquerda.
  • Sequências de escape representam caracteres especiais dentro de cadeias de caracteres.
  • Use cadeias de caracteres para identificadores longos cujos dígitos exatos precisam ser preservados.
  • Chaves de objeto repetidas são inseguras; JSON.parse mantém o último valor.

5.2 Converter valores em texto JSON com JSON.stringify

JSON.stringify converte valores JavaScript compatíveis em texto JSON. Decida o que o texto deve preservar antes de converter um registro com métodos ou valores de coleções.

Escreva texto compacto ou indentado
const person = { name: "Amara", age: 34, tags: ["admin"] };
const text = JSON.stringify(person);
// '{"name":"Amara","age":34,"tags":["admin"]}'

O resultado é uma cadeia de caracteres, então typeof text é "string". Propriedades próprias enumeráveis com chaves de cadeia de caracteres são escritas na ordem de Object.keys. JSON.stringify(person, null, 2) adiciona quebras de linha e dois espaços de indentação por nível. O segundo argumento é null porque nenhum substituidor está sendo usado. A indentação numérica é limitada a 10 espaços; uma cadeia de caracteres usada para indentação é limitada aos seus primeiros 10 caracteres.

Preveja valores descartados e alterados
const data = {
  a: undefined,
  b: () => 1,
  c: NaN,
  d: [undefined, Infinity]
};
JSON.stringify(data); // '{"c":null,"d":[null,null]}'

Uma propriedade de objeto que contém undefined, uma função ou um símbolo é omitida. Em um vetor, esse valor se torna null, preservando a posição. NaN e Infinity tornam-se null em ambos os lugares. No nível superior, valores não suportados como undefined ou uma função fazem stringify retornar undefined, não texto JSON.

Um Date escreve sua cadeia ISO em UTC por meio de toJSON. Entradas comuns de Map e Set não são escritas, então qualquer uma das coleções se torna {}. Converta valores de Set em um vetor e entradas de Map em pares ou em um objeto com chaves de cadeia de caracteres antes de escrevê-los.

Uma referência circular e um BigInt comum como 10n causam um TypeError. Referências compartilhadas que não formam um ciclo podem ser serializadas, mas JSON não preservará sua identidade compartilhada.

Escolha dados com um substituidor
const user = { name: "Rae", email: "rae@example.com", password: "x9!k", age: 31 };
JSON.stringify(user, ["name", "email"]);
// '{"name":"Rae","email":"rae@example.com"}'

Um vetor substituidor seleciona nomes de propriedades. Uma função substituidora transforma valores à medida que são visitados, começando com toda a entrada sob a chave "":

JSON.stringify(user, (key, value) =>
  key === "password" ? undefined : value
);

Retornar undefined omite uma propriedade de objeto, transforma uma posição de vetor em null ou causa um resultado geral undefined quando retornado para a raiz. Retorne o valor inalterado para os dados que você quer manter.

O método toJSON() de um objeto pode escolher sua representação. Para { celsius: 21, toJSON() { return { c: this.celsius }; } }, a conversão em texto escreve '{"c":21}'.

Não construa JSON juntando você mesmo cadeias de caracteres entre aspas: aspas internas ou novas linhas podem invalidar sua sintaxe. Também não converta novamente em texto um texto já serializado esperando uma representação de objeto. Converter '{"a":1}' em texto codifica uma cadeia de caracteres; analisar esse resultado uma vez retorna uma cadeia de caracteres, não um objeto.

Principais conclusões

  • JSON.stringify geralmente retorna texto JSON; valores não suportados no nível superior podem retornar undefined.
  • Propriedades de objeto não suportadas desaparecem, enquanto itens de vetor não suportados se tornam null.
  • Datas tornam-se cadeias de caracteres; Map e Set precisam de conversão explícita.
  • Estruturas circulares e BigInts comuns lançam TypeError.
  • Substituidores e toJSON controlam a representação escrita.
  • Converter texto JSON novamente codifica uma cadeia de caracteres, não o objeto contido nela.

5.3 Converter texto JSON em valores com JSON.parse

JSON.parse lê texto JSON e retorna o valor que ele descreve. A análise sintática verifica a sintaxe do texto; verificar se o resultado é adequado ao seu programa é uma tarefa separada.

Leia o valor e depois examine seus campos
const data = JSON.parse('{"city":"Lima","tempC":19.5}');
data.tempC + 1; // 20.5

As aspas simples externas delimitam uma cadeia de caracteres JavaScript. As aspas duplas dentro dela pertencem ao JSON. A análise sintática cria um objeto comum com uma propriedade numérica tempC. Um texto que descreve um vetor produz um vetor; textos JSON primitivos produzem seus valores primitivos correspondentes.

Dados que já são um objeto não precisam de uma etapa de análise sintática. JSON.parse({ a: 1 }) primeiro converte esse argumento em "[object Object]" e depois lança um SyntaxError. JSON.parse(undefined) também falha porque "undefined" não é texto JSON válido.

Trate texto inválido
function safeParse(text, fallback) {
  try {
    return JSON.parse(text);
  } catch (error) {
    return fallback;
  }
}
safeParse("{ok:true}", null); // null

Uma entrada malformada, incluindo uma cadeia de caracteres vazia, cadeias JSON entre aspas simples, chaves sem aspas e vírgulas finais, lança um SyntaxError. Capturar essa falha dá ao programa uma alternativa de contingência definida, em vez de interrompê-lo. Um null analisado com sucesso também é possível, então escolha como quem chama distinguirá uma alternativa de contingência de dados válidos quando essa diferença importar.

Restaure valores selecionados com uma função restauradora

Uma data armazenada como texto retorna como uma cadeia de caracteres. Um vetor de pares chave-valor permanece um vetor até que new Map(pairs) o transforme em um Map. Funções omitidas durante a escrita não podem ser recuperadas do texto restante.

const text = '{"title":"Dentist","due":"2026-03-01T09:00:00.000Z"}';
const event = JSON.parse(text, (key, value) =>
  key === "due" ? new Date(value) : value
);

A função restauradora visita valores internos antes de seus contêineres, terminando com o resultado inteiro sob a chave "". Retornar um valor substitui o valor atual. Retornar undefined remove essa propriedade; retorná-lo para a raiz faz todo o resultado da análise ser undefined. Esquecer return value para outras chaves pode, portanto, apagar os dados que você queria manter.

Verifique a estrutura e planeje uma conversão de ida e volta

JSON válido ainda pode ter os tipos errados. Analisar '{"temp":"19"}' deixa uma cadeia de caracteres, então data.temp + 1 concatenaria para "191". Verifique campos e tipos obrigatórios, como typeof data?.temp === "number", antes de calcular. Converta com Number apenas quando o formato pretendido permitir uma cadeia numérica; o encadeamento opcional e ?? podem tratar campos que podem estar ausentes.

Para const settings = { theme: "dark", volume: 0.8, recent: ["a.txt"] };, a conversão em texto produz 48 caracteres de texto JSON. A análise sintática restaura os mesmos dados dos campos, mas loaded === settings é falso porque ela cria novos objetos. Um Date retorna como uma cadeia de caracteres, uma propriedade de objeto com valor undefined desaparece e um Set não convertido retorna como {}. Converta valores especiais antes de escrever e restaure seus tipos pretendidos após a leitura.

Principais conclusões

  • JSON.parse lê texto e lança SyntaxError para JSON malformado.
  • Uma análise sintática bem-sucedida não verifica os campos obrigatórios nem seus tipos.
  • Uma função restauradora visita primeiro os valores filhos e deve retornar os valores que você quer manter.
  • Conversões de ida e volta por JSON criam novos objetos e preservam apenas dados representáveis.
  • Restaure explicitamente os tipos de coleções e datas após a análise sintática.

Exercícios resolvidos de Objetos e JSON

5 Lições Interativas

1

Acompanhar um registro de remessa

16 passos
Crie, examine e copie um registro aninhado enquanto acompanha quais valores são compartilhados.
  1. 1
    IntroduçãoConstrua um registro que você possa examinar

    Uma remessa combina um ID, um destino e registros de pacotes. Você vai construí-la, examinar seus campos e acompanhar dados compartilhados e copiados. Dois nomes podem guardar uma referência ao mesmo registro, e uma cópia rasa ainda compartilha os níveis aninhados, então uma atualização pode alcançar dados que você pretendia manter separados.

    Os exemplos da remessa continuam entre os slides, a menos que uma etapa crie explicitamente um objeto separado.

  2. 2
    ExemploCrie a remessa
    const shipment = {
      id: "s12",
      destination: "Porto",
      delayMin: 0
    };
    

    O literal cria três propriedades. O atraso é medido em minutos e pode ser zero. shipment.destination lê "Porto". Const permite atualizações das propriedades.

  3. 3
    ExemploEscolha um campo durante a execução do programa
    const field = "destination";
    shipment[field] = "Braga";
    shipment.checked = true;
    

    O acesso por colchetes avalia field e atualiza a propriedade de destino. A atribuição também adiciona checked porque ela não existia antes. A remessa continua com a mesma identidade; nenhuma das operações substitui o objeto externo. Escrever shipment.field criaria uma propriedade separada literalmente chamada "field".

  4. 4
    DesafioLeia um nome computado

    O que shipment[field] lê agora, e a remessa tem uma propriedade própria field?

    ---reveal---

    Ela lê "Braga". A variável field contém a chave "destination", então tanto a atualização quanto a leitura acessam essa propriedade. Object.hasOwn(shipment, "field") é false porque nenhuma propriedade literal field foi criada. Uma variável usada para escolher uma propriedade não se torna parte do registro.

  5. 5
    ExplicaçãoVerifique zero sem perdê-lo

    shipment.delayMin é zero, então uma condição que testa se o valor é avaliado como verdadeiro ignora seu corpo. A propriedade continua existindo.

    Object.hasOwn(shipment, "delayMin") retorna true. Use uma verificação de propriedade própria para campos armazenados; o operador in também inclui propriedades herdadas.

  6. 6
    ExemploLeia os pares chave-valor
    const pairs = Object.entries(shipment);
    const count = Object.keys(shipment).length;
    

    Agora há quatro campos próprios enumeráveis com chaves de cadeia de caracteres, incluindo checked. Entries fornece um par [key, value] para cada um. Você pode usar o laço for (const [key, value] of pairs) para examinar ambas as partes. Um laço for...of direto sobre o objeto comum shipment lançaria um erro porque esse objeto não é iterável.

  7. 7
    DesafioSepare existência de valor

    Suponha que shipment.note = undefined; seja adicionado. O que shipment.note e Object.hasOwn(shipment, "note") retornam?

    ---reveal---

    Eles retornam undefined e true. A atribuição cria a propriedade mesmo que seu valor seja undefined. Excluir a propriedade mudaria o resultado da verificação de existência para false, enquanto uma leitura posterior ainda produziria undefined. O valor sozinho não consegue distinguir essas duas situações.

  8. 8
    AnalogiaAcompanhe dois caminhos até um registro

    Uma referência funciona como um caminho até um registro: copiar o caminho oferece outra maneira de chegar ao mesmo destino. Isso não constrói um segundo registro.

    const alias = shipment;
    alias.checked = false;
    

    shipment.checked agora também é false. Ambos os nomes de variáveis acessam um objeto, então alias === shipment é true. Referências iguais explicam a atualização compartilhada; nenhuma etapa de sincronização foi executada entre duas cópias.

  9. 9
    ExemploAdicione dados que uma cópia superficial compartilhará
    shipment.packages = [{ massG: 450 }, { massG: 700 }];
    const shallow = { ...shipment };
    shallow.destination = "Faro";
    shallow.packages[0].massG = 500;
    

    O novo registro externo tem seu próprio destino, então shipment.destination continua sendo Braga. Seu valor packages é a mesma referência de vetor de antes. Seguir esse caminho compartilhado também altera para 500 a massa do primeiro pacote na remessa original.

  10. 10
    ExemploFaça uma cópia profunda de dados compatíveis
    const deep = structuredClone(shipment);
    deep.packages[0].massG = 600;
    

    O primeiro pacote original permanece com 500 g porque a cópia profunda tem seu próprio vetor aninhado e seus próprios objetos de pacote. Esse registro contém apenas dados compatíveis. Se contivesse uma propriedade cujo valor fosse uma função, structuredClone lançaria DataCloneError em vez de descartar silenciosamente esse método.

  11. 11
    DesafioPreveja o alcance do congelamento

    Execute estas instruções. A atribuição aninhada lança um erro e qual é a segunda massa depois dela?

    Object.freeze(shipment);
    shipment.packages[1].massG = 750;
    

    ---reveal---

    Ela é bem-sucedida e define a massa como 750. Congelar shipment protege suas propriedades próprias, mas não o vetor referenciado nem seus registros. Reatribuir shipment.destination em modo estrito lançaria TypeError; essa atribuição aninhada acessa outro objeto, que não está congelado.

  12. 12
    ExemploCalcule o total atual
    const totalG = shipment.packages.reduce(
      (sum, pack) => sum + pack.massG, 0
    );
    

    Após as atualizações anteriores, a remessa original contém massas de 500 e 750 g. Reduce começa em zero, soma 500 e depois 750, produzindo 1250. O total é calculado a partir dos pacotes atuais. Se suas massas mudarem depois, execute o cálculo novamente; esse número armazenado não se recalcula sozinho.

  13. 13
    DicaProteja um caminho opcional
    const contactName = shipment.contact?.name ?? "Unassigned";
    

    Não há propriedade contact no registro, então o encadeamento opcional resulta em undefined e a alternativa de contingência fornece "Unassigned". Esse caminho pode estar ausente. Mantenha os campos obrigatórios visíveis para validação em vez de usar valores padrão silenciosamente para todos os erros. A alternativa para valores nulos ou indefinidos também preserva um nome intencionalmente vazio, diferentemente de uma alternativa com OU lógico.

  14. 14
    DesafioMantenha um zero válido

    O que shipment.delayMin ?? 10 e shipment.delayMin || 10 retornam?

    ---reveal---

    O primeiro retorna 0; o segundo retorna 10. A coalescência nula substitui apenas null ou undefined, enquanto o OU lógico substitui todo valor avaliado como falso. Essa remessa tem um atraso registrado de zero minuto, então tratá-lo como ausente introduziria um atraso que os dados armazenados nunca informaram.

  15. 15
    DesafioCombine uma cópia com uma atualização opcional

    Um novo registro é criado com const next = { ...shipment }; e, em seguida, next.packages[0].massG = 520;. O que acontece com a primeira massa de shipment, e next é o mesmo objeto externo?

    ---reveal---

    A massa original se torna 520 porque o vetor aninhado é compartilhado. next === shipment é false porque o espalhamento criou um novo objeto externo. Copiar o registro externo separa as atribuições às suas próprias propriedades, mas não torna independente todo um caminho aninhado.

  16. 16
    RecapitulaçãoEscolha a verificação adequada à tarefa

    Escolha uma propriedade por chave literal ou computada e distinga a existência do fato de um valor ser avaliado como verdadeiro. Antes de uma atualização, acompanhe se seu caminho chega a dados compartilhados.

    Copie níveis aninhados que precisam ser independentes. Recalcule totais derivados após suas entradas mudarem.

2

Manter uma ação conectada ao seu objeto

12 passos
Acompanhe chamadas de método, contexto capturado e funções de retorno com um pequeno contador.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoAcompanhe uma ação ao ser passada adiante
  2. 2
    ExemploCrie e chame uma ação
  3. 3
    DesafioLeia a ação sem executá-la
  4. 4
    ExemploEmpreste a função comum
  5. 5
    DesafioDesvincule o método emprestado
  6. 6
    Ideia-chaveColoque uma função de seta dentro do método
  7. 7
    ExemploEnvolva a chamada necessária
  8. 8
    ExemploVincule uma função de retorno uma vez
  9. 9
    DesafioEscolha entre execução imediata ou posterior
  10. 10
    DicaDê prioridade a uma vinculação existente
  11. 11
    DesafioAcompanhe um método vinculado por outro objeto
  12. 12
    RecapitulaçãoLeia a forma da chamada
3

Extrair opções e construir um registro atualizado

14 passos
Leia padrões de fora para dentro e depois copie apenas os níveis que precisam mudar.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoLeia a sintaxe compacta em pequenas etapas
  2. 2
    ExemploSelecione e renomeie campos
  3. 3
    ExemploAcesse um padrão aninhado
  4. 4
    DesafioLeia um campo aninhado renomeado
  5. 5
    DesafioMantenha null distinto de um valor ausente
  6. 6
    ExemploExtraia um intervalo retornado
  7. 7
    ExemploColete o restante em seu próprio vetor
  8. 8
    DesafioTroque valores antes de usá-los
  9. 9
    ExemploMescle valores padrão com substituições
  10. 10
    ExemploCopie o nível aninhado que muda
  11. 11
    ConexãoRemova um campo do novo registro
  12. 12
    DesafioEscolha uma atualização independente
  13. 13
    DesafioConecte padrões de pares chave-valor ao espalhamento
  14. 14
    RecapitulaçãoIdentifique a função antes de acompanhar os valores
4

Acompanhar contagens e pertinência de valores únicos

11 passos
Use Map para valores indexados por chaves que mudam e Set para pertinência, depois compare coleções.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoEscolha o que a coleção deve manter
  2. 2
    ExemploCrie contagens com métodos de Map
  3. 3
    DicaMantenha entradas separadas de propriedades
  4. 4
    DesafioMantenha distintos os tipos de chave
  5. 5
    ExemploReutilize uma chave que é objeto
  6. 6
    ExemploColete rótulos únicos
  7. 7
    DesafioDecida se registros são duplicatas
  8. 8
    ExemploEncontre os rótulos compartilhados e ausentes
  9. 9
    Ideia-chaveMude a pergunta sobre pertinência
  10. 10
    DesafioRelacione contagens à pertinência
  11. 11
    RecapitulaçãoEscolha a estrutura adequada à operação
5

Escrever, ler e verificar dados JSON

14 passos
Planeje uma representação compatível com JSON, trate texto inválido e restaure os tipos pretendidos.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoPlaneje as duas direções da conversão
  2. 2
    ExplicaçãoLeia texto como texto
  3. 3
    DesafioCorrija um problema de sintaxe
  4. 4
    ExemploExamine as configurações em uso
  5. 5
    ExemploConverta a coleção antes de escrever
  6. 6
    DicaDeixe o serializador aplicar sequências de escape
  7. 7
    DesafioPreveja um item de vetor não suportado
  8. 8
    ExemploAnalise e restaure as operações de pertinência
  9. 9
    ExemploTrate texto malformado de forma planejada
  10. 10
    DesafioVerifique um valor válido, mas inadequado
  11. 11
    ExplicaçãoRestaure um campo com uma função restauradora
  12. 12
    DesafioPreserve a distinção entre chaves de Map
  13. 13
    ConexãoMantenha clonagem e troca de dados separadas
  14. 14
    RecapitulaçãoVerifique sintaxe, estrutura e representação

Questões de Objetos e JSON

50 Questões de Prática em 5 conjuntos

Conjunto 1: Aplicar padrões e preservar objetos receptores10 Questões de Prática

Questão 1 de 10

Qual é o valor final de loaded?

const loaded = JSON.parse('{"count":4,"tag":"a"}', (key, value) => {
  if (key === "count") return value * 2;
});
  1. undefined
  2. { count: 8, tag: "a" }
  3. { count: 8 }
  4. {}
Mostrar respostaOcultar resposta
Resposta: A
Count primeiro se torna 8, mas todas as outras visitas retornam undefined porque não há instrução return para outras chaves. Isso remove tag e, na visita final à raiz com a chave "", remove o resultado inteiro. Manter apenas { count: 8 } deixaria de considerar que a função restauradora também processa a raiz.

Questão 2 de 10

O que acontece quando esse texto é analisado?

JSON.parse('{"mode":"fast","mode":"slow"}');
  1. Retorna { mode: "fast" }.
  2. Retorna { mode: "slow" }.
  3. Lança um SyntaxError.
  4. Retorna { mode: ["fast", "slow"] }.
Mostrar respostaOcultar resposta
Resposta: B
A análise sintática em JavaScript mantém o último valor para o nome mode repetido, "slow". Nomes únicos são recomendados, mas esse nome repetido não faz JSON.parse lançar SyntaxError.

Questão 3 de 10

O que trip.host?.name ?? "Guest" retorna?

const trip = { host: null };
  1. null
  2. undefined
  3. "Guest"
  4. Um TypeError
Mostrar respostaOcultar resposta
Resposta: C
O host nulo faz o encadeamento opcional produzir undefined, e então a alternativa de contingência fornece "Guest". Retornar undefined considera o primeiro operador, mas deixa de fora a alternativa de contingência.

Questão 4 de 10

Quais são os valores finais de a.level e a === b?

const a = { level: 2 };
const b = a;
b.level = 5;
  1. 5 e true
  2. 2 e false
  3. 5 e false
  4. 2 e true
Mostrar respostaOcultar resposta
Resposta: A
Atribuir a a b copia a referência ao objeto existente. Atualizar b.level altera, portanto, o objeto também acessado por a, então o nível é 5 e a identidade é compartilhada. Tratar essa atribuição como uma cópia do registro deixaria incorretamente o nível original em 2.

Questão 5 de 10

Quais são os valores de source.mode e source.layout.width depois disso?

const source = { mode: "day", layout: { width: 40 } };
const copy = { ...source };
copy.mode = "night";
copy.layout.width = 60;
  1. "night" e 60
  2. "day" e 40
  3. "night" e 40
  4. "day" e 60
Mostrar respostaOcultar resposta
Resposta: D
O espalhamento cria um objeto externo diferente, então atribuir um valor ao seu mode não altera source.mode. Ambos os registros ainda contêm a mesma referência layout, fazendo a largura aninhada ser 60 em ambos. Manter a largura em 40 exigiria uma cópia aninhada separada, que esse código não cria.

Questão 6 de 10

Qual função pode ser passada a map para que cada chamada atualize tally?

const tally = { n: 0, tick() { return ++this.n; } };
const result = ["x", "y"].map(/* callback */);
  1. tally.tick
  2. () => tally.tick()
  3. tally.tick()
  4. () => tally.tick
Mostrar respostaOcultar resposta
Resposta: B
A função envoltória de seta executa uma chamada de método com tally como objeto receptor cada vez que map a chama. Passar tally.tick desvincula o método comum e perde esse objeto receptor. Adicionar parênteses fora de uma função envoltória o executa imediatamente e passa um número, enquanto retornar tally.tick apenas retorna a função sem executá-la.

Questão 7 de 10

Este código é executado no nível superior de um módulo. O que acontece quando card.read() é chamado?

const card = { title: "Basin", read: () => this.title };
  1. Lança um TypeError.
  2. Retorna "Basin".
  3. Retorna undefined.
  4. Lança um ReferenceError.
Mostrar respostaOcultar resposta
Resposta: A
A função de seta captura o this do nível superior do módulo, que é undefined. Ler this.title lança, portanto, TypeError. Um literal de objeto não fornece um novo this a uma função de seta, então a chamada com aparência de método não pode fazê-la retornar "Basin"; um método comum usaria card como objeto receptor.

Questão 8 de 10

Após next.panel.width = 90, quais são os valores de next.mode e base.panel.width?

const base = { mode: "wide", panel: { width: 50 } };
const next = { mode: "small", ...base, panel: { ...base.panel } };
  1. "small" e 50
  2. "wide" e 90
  3. "small" e 90
  4. "wide" e 50
Mostrar respostaOcultar resposta
Resposta: D
O espalhamento de base vem depois do primeiro valor de mode e o sobrescreve com "wide". A propriedade panel final cria um objeto aninhado separado, então alterar sua largura deixa a original em 50. Prever 90 para a original deixaria de considerar esse segundo espalhamento, enquanto "small" ignoraria a ordem de sobrescrita.

Questão 9 de 10

Qual valor size recebe?

const { size = 6 } = {};
  1. undefined
  2. 6
  3. null
  4. 0
Mostrar respostaOcultar resposta
Resposta: B
A propriedade size ausente fornece undefined, então o valor padrão atribui 6. Undefined permaneceria apenas sem o valor padrão; o padrão não cria size na origem.

Questão 10 de 10

Qual vetor essa expressão produz?

[...new Set(["red", "blue", "red", "green", "blue"])];
  1. ["blue", "green", "red"]
  2. ["red", "green", "blue"]
  3. ["red", "blue", "green"]
  4. ["red", "blue", "red", "green", "blue"]
Mostrar respostaOcultar resposta
Resposta: C
Um Set mantém cada cadeia de caracteres uma vez na ordem em que aparece pela primeira vez: red, depois blue e depois green. Espalhar esses valores cria um vetor na mesma ordem. Isso não ordena os valores, e encontrar uma duplicata não move o valor existente para o fim da coleção.
Conjunto 2: Transformar coleções e recuperar dados10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Qual vetor é retornado neste módulo?

function scale(n) { return this.factor * n; }
const twice = scale.bind({ factor: 2 });
const obj = { factor: 9, twice };
[obj.twice(3), twice.call({ factor: 5 }, 4)];
  1. [27, 20]
  2. [6, 8]
  3. [6, 20]
  4. [27, 8]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

O que é retornado?

function combine(first, ...others) {
  return [first, others.length];
}
combine(...[7, 3, 8, 2]);
  1. [7, 4]
  2. [[7, 3, 8, 2], 0]
  3. [7, 3]
  4. [7, 2]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Qual objeto a expressão cria?

Object.fromEntries(
  Object.entries({ north: 3, south: 5 })
    .map(([key, value]) => [key, value + 2])
);
  1. { north: 5, south: 7 }
  2. { north: 3, south: 5 }
  3. { north: 6, south: 10 }
  4. { 5: "north", 7: "south" }
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

O que options.limit ?? 12 retorna?

const options = { limit: 0 };
  1. 12
  2. undefined
  3. 0
  4. null
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

O que add deve retornar para que basket.add("pear").add("fig") use o mesmo basket duas vezes?

const basket = {
  items: [],
  add(item) { this.items.push(item); /* return here */ }
};
  1. this.items
  2. item
  3. this.items.length
  4. this
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Quais são os valores de items[0].done, next[1] === items[1] e next === items?

const items = [{ id: 4, done: false }, { id: 9, done: false }];
const next = items.map(item =>
  item.id === 4 ? { ...item, done: true } : item
);
  1. true, true, false
  2. false, true, false
  3. false, false, false
  4. false, true, true
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Por que lookup.get({ code: 8 }) é undefined?

const key = { code: 8 };
const lookup = new Map([[key, "ready"]]);
  1. A consulta usa uma referência a outro objeto.
  2. Map converte as duas chaves em cadeias diferentes.
  3. Map ignora chaves que são objetos ao criar entradas.
  4. A chave deve ser convertida primeiro em texto JSON.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Quais são os tamanhos de a.difference(b) e a.symmetricDifference(b)?

const a = new Set([2, 4, 6]);
const b = new Set([4, 8]);
  1. 1 e 1
  2. 3 e 2
  3. 2 e 4
  4. 2 e 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Que texto isso produz?

JSON.stringify({ label: "Arc", count: 3 }, ["label"]);
  1. '{"label":"Arc","count":3}'
  2. '{"label":"Arc"}'
  3. '["label"]'
  4. '{"label":"Arc","count":null}'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Este módulo é executado sem uma função restauradora. Quais são os valores de typeof loaded.due e loaded === original?

const original = { due: new Date("2026-07-12T00:00:00.000Z") };
const loaded = JSON.parse(JSON.stringify(original));
  1. "object" e false
  2. "string" e true
  3. "object" e true
  4. "string" e false
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 3: Ler registros e acompanhar valores10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Quais são os valores de m.size e m.get(2)?

const m = new Map([[2, "number"], ["2", "text"]]);
  1. 1 e "text"
  2. 2 e "text"
  3. 1 e "number"
  4. 2 e "number"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Qual valor third recebe?

const [, , third] = [4, 9, 12, 18];
  1. 4
  2. 9
  3. 12
  4. 18
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

O que sensor[field] retorna?

const sensor = { tempC: 16, field: "room" };
const field = "tempC";
  1. "room"
  2. 16
  3. "tempC"
  4. undefined
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

O que Object.hasOwn(record, "enabled") retorna?

const record = { enabled: false };
  1. false
  2. undefined
  3. null
  4. true
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Quais são os valores de record.region e record.key?

const key = "region";
const record = { [key]: "east" };
record[key] = "west";
  1. "west" e undefined
  2. "east" e "west"
  3. undefined e "west"
  4. "west" e "east"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Qual é o valor de meter.value após essa chamada?

const meter = {
  value: 7,
  add() { this.value += 3; }
};
meter.add();
  1. 7
  2. 3
  3. 10
  4. undefined
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

O que right.read() retorna?

const left = { name: "Ivo", read() { return this.name; } };
const right = { name: "Nia", read: left.read };
  1. "Ivo"
  2. "Nia"
  3. undefined
  4. Um TypeError
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Quais são os valores de title e score após a desestruturação?

const { name: title, score = 8 } = { name: "Reef", score: null };
  1. "Reef" e null
  2. "Reef" e 8
  3. undefined e 8
  4. undefined e null
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um arquivo de dados deve preservar os dígitos exatos do ID 9007199254740997 e ser analisado como JSON. Qual texto de registro atende às duas necessidades?
  1. {"id":9007199254740997,"active":true}
  2. {id:"9007199254740997",active:true}
  3. {"id":"9007199254740997","active":true}
  4. {"id":'9007199254740997',"active":true}
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Que texto é retornado?

JSON.stringify({
  note: undefined,
  values: [undefined, NaN],
  ok: false
});
  1. '{"values":[null,null],"ok":false}'
  2. '{"note":null,"values":[null,null],"ok":false}'
  3. '{"values":[],"ok":false}'
  4. '{"values":[null,null]}'
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 4: Diagnosticar atualizações e chamadas10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Qual é o valor de typeof box.open?

const box = { open() { return "opened"; } };
  1. "function"
  2. "string"
  3. "object"
  4. "undefined"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Quais são os valores de base.inner.n, clone.inner.n e copy.inner.n ao final?

const base = { inner: { n: 2 } };
const copy = { ...base };
const clone = structuredClone(base);
Object.freeze(base);
copy.inner.n = 7;
clone.inner.n = 9;
  1. 2, 9, 7
  2. 9, 9, 9
  3. 2, 9, 2
  4. 7, 9, 7
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Qual vetor Object.keys(data) retorna?

const data = { z: 1, "10": 2, "02": 3, "2": 4, a: 5 };
  1. ["z", "10", "02", "2", "a"]
  2. ["2", "10", "z", "02", "a"]
  3. ["02", "2", "10", "z", "a"]
  4. ["2", "02", "10", "z", "a"]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Quanto vale totalG, e alterar heavy.massG também altera load.items[1].massG?

const load = { items: [
  { massG: 120, qty: 2 },
  { massG: 300, qty: 1 }
] };
const heavy = load.items.find(x => x.massG > 200);
const totalG = load.items.reduce((s, x) => s + x.massG * x.qty, 0);
heavy.massG = 350;
  1. 540; sim, passa a ser 350.
  2. 590; sim, passa a ser 350.
  3. 540; não, continua sendo 300.
  4. 420; sim, passa a ser 350.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

O que b.labels() retorna neste módulo?

const a = {
  prefix: "A",
  names: ["oak"],
  labels() { return this.names.map(n => this.prefix + n); }
};
const b = { prefix: "B", names: ["elm"], labels: a.labels };
  1. ["Aoak"]
  2. ["Aelm"]
  3. ["Belm"]
  4. Lança um TypeError.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

O que acontece quando read() e read({ prefs: null }) são chamados separadamente?

function read({ prefs: { theme = "light" } = {} } = {}) {
  return theme;
}
  1. Ambas as chamadas retornam "light".
  2. A primeira retorna "light"; a segunda lança TypeError.
  3. A primeira lança TypeError; a segunda retorna null.
  4. A primeira retorna undefined; a segunda retorna null.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Qual é o valor de tail?

const [head, ...tail] = [6, 8, 11];
  1. [6, 8, 11]
  2. 8
  3. [11]
  4. [8, 11]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Quais são os valores de m.size e [...m.keys()]?

const m = new Map([["p", 1], ["q", 2]]);
m.set("p", 4);
m["r"] = 5;
m.delete("q");
m.set("q", 6);
  1. 3 e ["p", "r", "q"]
  2. 2 e ["q", "p"]
  3. 2 e ["p", "q"]
  4. 3 e ["p", "q", "r"]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Por que JSON.parse('{"depthM":+7}') falha?
  1. Números JSON não podem começar com sinal de adição.
  2. Números JSON não podem ser números inteiros.
  3. Nomes de propriedades JSON não podem conter maiúsculas.
  4. Objetos JSON também devem conter um valor de texto.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Quais são os valores de result.count e result.total?

const result = JSON.parse('{"count":"6","total":12}',
  (key, value) => key === "count" ? Number(value) : value
);
result.total += result.count;
  1. "6" e "126"
  2. 6 e "126"
  3. 6 e 18
  4. undefined e NaN
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 5: Combinar escolhas de dados e regras de conversão10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Após publicCopy.profile.name = "New", qual é o valor de source.profile.name, e source ainda possui a propriedade própria secret?

const source = { secret: "s", profile: { name: "Old" } };
const { secret, ...publicCopy } = source;
  1. "Old"; sim.
  2. "New"; sim.
  3. "New"; não.
  4. "Old"; não.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Qual é o valor final de counts.get("moss")?

const counts = new Map();
for (const word of ["moss", "fern", "moss", "moss"]) {
  counts.set(word, (counts.get(word) ?? 0) + 1);
}
  1. 1
  2. 2
  3. 4
  4. 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Quais são os valores de records.size e ids.size?

const x = { id: 7 };
const records = new Set([x, x, { id: 7 }]);
const ids = new Set([...records].map(r => r.id));
  1. 2 e 1
  2. 1 e 1
  3. 3 e 1
  4. 2 e 2
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Qual é o valor de typeof JSON.parse(text)?

const text = JSON.stringify('{"x":3}');
  1. "string"
  2. "object"
  3. "number"
  4. "undefined"
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Qual é o valor de Object.hasOwn(record, "old") após estas instruções?

const record = { old: undefined };
delete record.old;
  1. true
  2. false
  3. undefined
  4. Lança TypeError.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Quais são os valores de a === b, a.left === a.right e b.left === b.right?

const shared = { n: 1 };
const a = { left: shared, right: shared };
const b = JSON.parse(JSON.stringify(a));
  1. false, true, true
  2. true, true, true
  3. false, true, false
  4. false, false, false
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

O que saved() retorna?

const maker = {
  n: 5,
  make() { return () => this.n; }
};
const other = { n: 8, make: maker.make };
const saved = other.make().bind({ n: 12 });
  1. 5
  2. 12
  3. undefined
  4. 8
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

O que fixed.apply({ offset: 30 }, [4]) retorna?

function add(a, b) { return this.offset + a + b; }
const fixed = add.bind({ offset: 2 }, 7);
  1. 13
  2. 41
  3. 36
  4. NaN
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Quais são os valores de a, b e rest?

let a = 3, b = 8;
[a, b] = [b, a];
const [, ...rest] = [a, b, 13];
  1. 8, 8, [8, 13]
  2. 8, 3, [8, 3, 13]
  3. 8, 3, [3, 13]
  4. 3, 8, [8, 13]
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Um Map deve manter separadas a chave numérica 3 e a chave de cadeia de caracteres "3", com os valores "n" e "s". Qual par de conversões as preserva por meio de JSON?
  1. Escreva JSON.stringify(Object.fromEntries(m)); leia com new Map(Object.entries(JSON.parse(text))).
  2. Escreva JSON.stringify([...m]); leia com new Map(JSON.parse(text)).
  3. Escreva JSON.stringify(m); leia com new Map(Object.entries(JSON.parse(text))).
  4. Escreva JSON.stringify([...m.keys()]); leia com new Map(JSON.parse(text)).
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Travou em uma questão sua? Ajuda com Tarefas

Termos-Chave

79 Termos-Chave, cada um com sua definição

A

Aplicação parcial
A aplicação parcial fixa alguns argumentos agora para criar uma função que recebe os argumentos restantes quando for chamada mais tarde.
multiply.bind(null, 4) cria uma função que multiplica seu próximo argumento por quatro.
Argumento de indentação
O argumento de indentação é o terceiro argumento de stringify e controla os espaços ou uma cadeia curta usada para formatar texto JSON aninhado.
Passar null como substituidor e 2 como terceiro argumento faz cada nível aninhado usar dois espaços.
Argumento substituidor
Um argumento substituidor é o segundo argumento de stringify: um vetor de nomes de propriedades a incluir ou uma função que transforma os valores visitados.
Retornar undefined para uma propriedade privada de objeto a omite, enquanto retornar o valor original mantém os outros dados.
Atualização imutável
Uma atualização imutável constrói novos contêineres para os dados que mudam, preservando os contêineres originais e os valores compartilhados inalterados.
Uma função de retorno de map pode retornar uma cópia por espalhamento para o registro alterado e reutilizar todos os registros não afetados.

C

Cadeia de caracteres JSON
Uma cadeia de caracteres JSON é um dado de texto delimitado por aspas duplas, com sequências de escape para caracteres como aspas e quebras de linha.
Um valor de texto que contém aspas precisa de uma sequência de escape dentro das aspas duplas que o delimitam em JSON.
Chamada simples em modo estrito
Uma chamada simples em modo estrito chama uma função comum em modo estrito sem fornecer um objeto receptor, deixando seu valor de this como undefined.
Desvincular um método em f e chamar f() em um módulo pode falhar quando ele tenta ler this.name.
Chave de índice de vetor
Uma chave de índice de vetor é uma cadeia de caracteres padrão que representa um inteiro de 0 a 4294967294, ordenada numericamente antes das outras chaves próprias de cadeia de caracteres.
A chave "3" vem antes de "12" em Object.keys; "03" permanece entre as chaves comuns de cadeia de caracteres.
Coalescência nula
A coalescência nula fornece uma alternativa de contingência apenas quando seu operando esquerdo é null ou undefined, preservando outros valores avaliados como falsos.
settings.volume ?? 1 mantém um volume explícito de zero, enquanto settings.volume || 1 o substitui.
Coleção WeakMap
Um WeakMap associa valores a chaves que são objetos ou símbolos não registrados sem manter vivas chaves que, de outro modo, seriam inalcançáveis.
Um WeakMap pode associar metadados a um objeto sem adicionar campos a ele ou disponibilizar uma lista de entradas.
Coleção WeakSet
Um WeakSet registra a pertinência de objetos ou símbolos não registrados sem manter vivos membros que, de outro modo, seriam inalcançáveis, e não pode ser percorrido.
Um WeakSet pode marcar objetos processados sem mantê-los apenas porque foram processados alguma vez.
Conjunto (Set)
Um Set é uma coleção de valores únicos de qualquer tipo que preserva a ordem de inserção para iteração e não tem posições indexadas.
Adicionar "ready" duas vezes mantém um valor, enquanto adicionar dois registros separados com dados iguais mantém ambos.
Conversão de ida e volta
Uma conversão de ida e volta escreve dados em uma representação e os lê de volta, preservando apenas as informações que essa representação consegue expressar.
Uma conversão de ida e volta por JSON cria novos objetos e retorna um Date como texto, a menos que uma conversão restaure seu tipo.
Cópia profunda
Uma cópia profunda cria dados aninhados independentes e um novo valor externo, respeitando os tipos suportados pelo método de cópia.
Após uma chamada de structuredClone com dados compatíveis, editar um campo aninhado copiado deixa o campo original inalterado.
Cópia superficial
Uma cópia superficial cria um novo objeto ou vetor externo, mantendo referências a quaisquer objetos aninhados armazenados nele.
Atualizar o endereço aninhado de um registro copiado também pode atualizar o endereço compartilhado do registro original.

D

Dados aninhados
Dados aninhados colocam objetos ou vetores dentro de outros objetos ou vetores, de modo que um caminho precisa seguir várias etapas para alcançar um valor.
report.readings[0].tempC lê uma lista, seu primeiro registro e depois um campo de temperatura.
Desestruturação de objetos
A desestruturação de objetos lê propriedades selecionadas para variáveis fazendo a correspondência por seus nomes.
const { city, tempC } = reading; cria duas variáveis locais a partir de um registro meteorológico.
Desestruturação de vetores
A desestruturação de vetores lê valores de posições sucessivas de um iterável para um padrão entre colchetes.
const [low, high] = bounds; depende de bounds colocar o menor valor antes do maior.
Diferença
Uma diferença contém valores de uma primeira coleção que estão ausentes de uma segunda, então trocar as coleções de ordem pode alterar o resultado.
active.difference(blocked) mantém valores ativos que não aparecem no Set de bloqueados.
Diferença simétrica
Uma diferença simétrica contém valores presentes em exatamente uma de duas coleções, excluindo todos os valores compartilhados.
Comparar dois Sets de etiquetas dessa forma encontra as etiquetas que pertencem a uma lista, mas não a ambas.

E

Elemento rest de vetor
Um elemento rest de vetor reúne os valores restantes em um novo vetor e deve encerrar o padrão.
const [leader, ...others] = names; separa o primeiro nome de um vetor com os nomes restantes.
Encadeamento de métodos
O encadeamento de métodos chama um método no valor retornado pela chamada anterior.
list.add("a").add("b") funciona quando a primeira chamada retorna um objeto com o próximo método add.
Encadeamento opcional
O encadeamento opcional interrompe um acesso a propriedade, acesso por índice ou chamada quando o valor verificado é null ou undefined, produzindo undefined.
record.owner?.name permite que owner esteja ausente sem tentar ler um nome de undefined.
Entrada de Map
Uma entrada de Map associa uma chave a um valor e é mantida com métodos de Map, independentemente das propriedades comuns do objeto.
stock.set("tea", 4) altera uma entrada; stock["tea"] = 4 altera uma propriedade comum.
Erro de sintaxe (SyntaxError)
Um SyntaxError sinaliza sintaxe inválida, como texto malformado fornecido a JSON.parse.
Uma vírgula final em JSON externo pode ser capturada com try...catch para que o programa trate a falha.
Espalhamento de iteráveis
O espalhamento de iteráveis expande um iterável em elementos separados de vetor ou argumentos de chamada, lendo seus valores em sequência.
Math.max(...measurements) fornece cada item do vetor como um argumento separado para a função.
Espalhamento de objetos
O espalhamento de objetos copia propriedades próprias enumeráveis para um novo literal, com ocorrências posteriores sobrescrevendo valores anteriores da mesma chave.
{ ...base, active: true } copia base e depois fornece o valor final para active.
Existência de propriedade
A existência de propriedade significa que uma chave está presente, independentemente de seu valor armazenado ser avaliado como verdadeiro, avaliado como falso ou ser undefined.
Um registro com count: 0 ainda tem uma propriedade count; testar esse valor como condição não detecta sua presença.

F

Função envoltória de seta
Uma função envoltória de seta é uma função de retorno de seta cujo corpo executa a chamada de método pretendida mais tarde, mantendo explícito o objeto receptor dessa chamada.
Passar () => counter.tick() para map faz cada função de retorno chamar tick por meio do objeto counter.
Função restauradora
Uma função restauradora é uma função de retorno de JSON.parse que transforma valores após seus filhos, usando seus valores de retorno para substituí-los ou removê-los.
Uma função restauradora pode restaurar um campo de data conhecido e retornar todos os valores não relacionados sem alterá-los.
Função structuredClone
structuredClone copia valores JavaScript aninhados compatíveis, incluindo estruturas circulares, mas rejeita valores que são funções.
Um registro que contém vetores comuns pode ser clonado; incluir um método causa um DataCloneError.

I

Identidade do objeto
A identidade do objeto é a distinção entre um objeto específico e todos os outros, independentemente de seus campos terem valores iguais.
Dois registros criados separadamente com id: 9 são considerados diferentes por === apesar dos dados iguais.
Inteiro seguro
Um inteiro seguro é um inteiro de -9007199254740991 a 9007199254740991, intervalo em que Number do JavaScript mantém cada inteiro distinto e exato.
Um identificador fora do intervalo seguro pode ser enviado como uma cadeia de caracteres JSON para preservar cada dígito.
Interseção
Uma interseção contém apenas os valores presentes em ambas as coleções, deixando de fora os valores que ocorrem em apenas uma delas.
A interseção de IDs ativos com IDs aprovados encontra os IDs que atendem às duas condições de pertinência.
Iterável
Um iterável fornece uma sequência de valores para operações como for...of ou espalhamento em vetores.
Vetores, cadeias de caracteres, Maps e Sets podem ser desestruturados dessa forma; um registro comum não pode.

J

JSON
JSON é um formato de texto independente de linguagem que representa objetos, vetores, cadeias de caracteres, números, booleanos e null usando uma sintaxe restrita.
O texto {"ready":true} descreve um registro, enquanto true sozinho também é um texto JSON completo e válido.

L

Literal de objeto
Um literal de objeto cria um objeto diretamente com chaves e propriedades de chave-valor.
const reading = { tempC: 22 }; cria um registro que contém uma medição de temperatura.

M

Map
Um Map é uma coleção de entradas de chave-valor com chaves de qualquer tipo, que preserva a ordem em que suas chaves foram inseridas pela primeira vez.
A chave numérica 5 e a chave de cadeia de caracteres "5" permanecem entradas distintas quando armazenadas no mesmo Map.
Método
Um método é uma propriedade cujo valor é uma função chamada por meio de um objeto.
Chamar tracker.advance() executa a ação de tracker, enquanto ler tracker.advance retorna uma função.
Método apply
apply executa uma função imediatamente com um valor de this explícito e um vetor que contém seus argumentos comuns.
format.apply(reading, ["m", 2]) fornece o mesmo objeto receptor e os mesmos valores que format.call(reading, "m", 2).
Método bind
bind retorna uma nova função com um valor de this fixo e argumentos iniciais opcionais, deixando a execução para quando a nova função for chamada.
Guardar const next = meter.step.bind(meter); cria uma função de retorno que mantém meter como objeto receptor.
Método call
call executa uma função imediatamente com um valor de this explícito, seguido de argumentos comuns fornecidos um de cada vez.
format.call(reading, "m", 2) fornece a format o objeto receptor reading e dois argumentos separados.
Método desvinculado
Um método desvinculado é uma função lida de um objeto e passada ou armazenada sem preservar o objeto em sua expressão de chamada posterior.
const read = sensor.read; mantém a função, mas read() não fornece sensor como objeto receptor.
Método emprestado
Um método emprestado é uma função comum extraída de outro objeto e usada por meio de um novo objeto receptor sem alterar a própria função.
Atribuir b.read = a.read permite que b.read() use os dados de b quando a função lê por meio de this.
Método JSON.parse
JSON.parse lê texto JSON e retorna o valor JavaScript representado por ele, lançando um SyntaxError quando o texto está malformado.
Analisar um registro com count numérico 4 permite fazer operações aritméticas, enquanto count entre aspas continua sendo uma cadeia de caracteres.
Método JSON.stringify
JSON.stringify serializa valores JavaScript suportados em texto JSON, podendo selecionar dados e adicionar indentação para leitura.
JSON.stringify(settings, null, 2) escreve uma forma mais legível sem alterar as configurações representadas.
Método Map.groupBy
Map.groupBy é um método mais recente que agrupa itens iteráveis em vetores dentro de um Map, preservando o tipo e a identidade das chaves de grupo.
Agrupar registros por um objeto responsável compartilhado permite que essa mesma referência ao responsável recupere seu grupo.
Método Object.freeze
Object.freeze impede adições, exclusões e alterações nas propriedades próprias de um objeto, mas não congela objetos aninhados.
Em código estrito, atribuir um valor ao status de nível superior de um registro congelado lança um TypeError.
Método Object.fromEntries
Object.fromEntries cria um objeto a partir de pares chave-valor, sendo útil após uma transformação de pares ou a partir de um Map compatível.
Transformar o valor de cada par e reconstruir o objeto pode converter um registro inteiro de medições.
Método Object.groupBy
Object.groupBy é um método mais recente que agrupa itens iteráveis em vetores sob chaves selecionadas por uma função de retorno, em um objeto sem protótipo.
Agrupar tarefas por status fornece um vetor para tarefas concluídas e outro para tarefas pendentes.
Método toJSON
Um método toJSON retorna a representação compatível com JSON escolhida para um objeto, que stringify escreve no lugar do objeto original.
Um objeto de medição pode retornar um registro comum menor que contém os campos destinados à troca de dados.

N

Nome de propriedade computado
Um nome de propriedade computado avalia uma expressão entre colchetes para nomear uma propriedade em um literal.
Com const code = "es";, { [code]: "Hola" } cria uma propriedade chamada "es".
Notação de colchetes
A notação de colchetes avalia a expressão dentro dos colchetes para selecionar uma chave de propriedade.
Com const field = "heightM";, person[field] seleciona a medida de altura da pessoa.
Notação de ponto
A notação de ponto seleciona o nome literal de propriedade após um ponto.
profile.name sempre seleciona a propriedade chamada "name", mesmo que exista uma variável chamada name.

O

Objeto de opções
Um objeto de opções passa configurações nomeadas para uma função em vez de depender das posições dos argumentos.
Uma função que recebe { color, size } permite que quem a chama indique o significado de cada configuração sem depender da ordem das posições.
Objeto receptor
Um objeto receptor é o objeto fornecido como this em uma chamada de método comum.
Em account.describe(), account é o objeto receptor que o método usa para ler seus campos.
Ordem de inserção
A ordem de inserção é a sequência em que chaves ou valores distintos entram pela primeira vez em uma coleção, preservada pela iteração de Map e Set.
Atualizar uma entrada de Map mantém sua posição; excluí-la e inserir a chave novamente a coloca por último.

P

Padrão aninhado
Um padrão aninhado seleciona valores de uma estrutura interna enquanto desestrutura sua estrutura externa.
const { owner: { name } } = item; precisa de um objeto owner e declara apenas name.
Padrão de renomeação
Um padrão de renomeação lê uma propriedade para um nome local diferente usando dois-pontos.
const { title: label } = page; cria label sem declarar uma variável chamada title.
Palavra-chave this
A palavra-chave this designa o contexto atual de uma função; funções comuns geralmente o recebem da chamada e funções de seta mantêm um contexto externo.
O mesmo método de leitura comum não vinculado pode ler objetos diferentes quando chamado por meio de objetos receptores diferentes.
Par chave-valor
Um par chave-valor é uma sequência de dois itens cujo primeiro valor é uma chave de propriedade ou coleção e cujo segundo valor são os dados associados a ela.
Object.entries({ lake: 5 }) produz [["lake", 5]], pronto para um laço sobre chaves e valores.
Parâmetro rest
Um parâmetro rest reúne os argumentos restantes da função em um vetor verdadeiro e deve ser o último parâmetro da declaração.
function total(...values) pode usar reduce em values mesmo quando a chamada não fornece argumentos.
Posição ignorada
Uma posição ignorada consome um valor sem nomeá-lo em um padrão de desestruturação de vetores.
const [, second] = colors; ignora a primeira cor e nomeia apenas o próximo valor fornecido.
Propriedade
Uma propriedade associa uma chave de objeto a um valor, que pode ser um dado ou uma função.
A propriedade active em { active: false } existe mesmo que seu valor seja o booleano false.
Propriedade abreviada
Uma propriedade abreviada recebe seu nome e valor de uma variável de mesmo nome.
Com uma variável chamada city, o literal { city } cria o mesmo campo que { city: city }.
Propriedade globalThis
globalThis fornece uma forma padrão de se referir ao objeto global, que funções comuns em modo não estrito usam em uma chamada simples.
O objeto global de um navegador é window, mas uma chamada simples de função em modo estrito ainda recebe undefined como this.
Propriedade própria
Uma propriedade própria pertence diretamente a um objeto, de modo que uma verificação de propriedade própria não inclui propriedades acessadas por herança.
Object.hasOwn({}, "toString") é false, embora "toString" in {} seja true.

R

Referência
Uma referência conecta uma variável ou propriedade a um objeto, permitindo que vários nomes acessem e alterem o mesmo valor subjacente.
A atribuição const backup = record; oferece outra forma de acessar record sem copiar seus campos.
Referência circular
Uma referência circular é um caminho de referências entre objetos que retorna a um objeto já presente nesse caminho, o que o JSON comum não consegue codificar.
Adicionar record.self = record faz a chamada comum de JSON.stringify lançar um TypeError para esse registro.

S

Sequência de escape
Uma sequência de escape usa uma barra invertida e os caracteres seguintes para representar um caractere especial ou uma unidade de código UTF-16 dentro de uma cadeia de caracteres JSON.
Serializar uma mensagem com uma nova linha escreve uma sequência de escape em vez de colocar uma quebra de linha literal dentro da cadeia.
Serialização
A serialização converte valores em uso em uma representação que pode ser armazenada ou trocada, como o texto JSON produzido por stringify.
Um objeto de configurações deve ser serializado antes que um destino que aceite apenas texto possa receber sua estrutura.
Sintaxe abreviada de método
A sintaxe abreviada de método define um método comum diretamente por seu nome, parâmetros e corpo em um literal.
O membro reset() { this.n = 0; } define uma ação sem dois-pontos separados e sem a palavra-chave function.
Sintaxe rest de objetos
A sintaxe rest de objetos coleta propriedades próprias enumeráveis ainda não nomeadas em um padrão de desestruturação para um novo objeto superficial.
const { password, ...publicRecord } = user; deixa user intacto enquanto exclui password da cópia.
Subconjunto
Um subconjunto é uma coleção cujos valores pertencem todos a outra coleção, mesmo quando as duas coleções são iguais.
Um Set de permissões exigidas é um subconjunto das permissões concedidas apenas quando cada valor exigido foi concedido.

T

Teste de pertinência
Um teste de pertinência verifica se uma chave ou um valor está presente em uma coleção, independentemente dos dados armazenados sob essa chave.
map.has(key) pode encontrar uma entrada existente mesmo quando map.get(key) retorna undefined.
this léxico
This léxico é o valor de this ao redor que uma função de seta mantém onde é criada, sem ser afetado por um objeto receptor ou vinculação posterior.
Uma função de seta criada dentro de um método em execução pode manter o objeto desse método durante uma função de retorno de vetor.

U

União
Uma união contém todos os valores presentes em qualquer uma de duas coleções, com valores compartilhados incluídos apenas uma vez no Set resultante.
Se um grupo tem Ana e Bo e outro tem Bo e Cai, sua união tem as três pessoas.

V

Valor derivado
Um valor derivado é calculado a partir de outros dados armazenados, como um total a partir de itens, e pode ficar desatualizado se for armazenado separadamente.
Calcular a distância de uma rota a partir de seus trechos mantém o resultado consistente após a alteração de um trecho.
Valor padrão na desestruturação
Um valor padrão na desestruturação substitui um valor selecionado undefined, incluindo um campo ou uma posição ausente.
Em const { count = 2 } = { count: null };, o null explícito permanece apesar do valor padrão.
Verificação da estrutura dos dados
Uma verificação da estrutura dos dados verifica se um valor analisado tem os campos, tipos de contêiner e tipos de valor de que o programa precisa antes de usá-lo.
JSON válido que contém uma contagem como cadeia de caracteres ainda precisa ser verificado antes de um programa tratar esse campo como número.

Sobre esta aula

Por StudeliRelatar um erro

Crie seus próprios Materiais de Estudo

Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.

Começar