JSON (JavaScript Object Notation) é um formato leve de troca de dados, fácil de ler e escrever para humanos e máquinas. Em JavaScript, JSON é nativamente suportado por meio dos métodos JSON.parse e JSON.stringify, que permitem converter objetos JavaScript em strings JSON e vice-versa. Esta aula explora o uso prático de JSON, incluindo manipulação de dados, pegadinhas comuns e integração com APIs.

O que é JSON

JSON é um formato de texto baseado em um subconjunto da sintaxe de objeto JavaScript, mas é independente de linguagem. Ele é amplamente utilizado para transmitir dados entre um servidor e um cliente web, ou entre diferentes partes de um sistema. A estrutura básica consiste em pares de chave-valor, onde as chaves são strings e os valores podem ser strings, números, booleanos, arrays, objetos ou null.

Exemplo de um objeto JSON:

{
  "nome": "João",
  "idade": 30,
  "email": "joao@example.com",
  "ativo": true,
  "endereco": {
    "cidade": "São Paulo",
    "estado": "SP"
  },
  "telefones": ["11999999999", "11888888888"]
}

Note que as chaves e strings devem estar entre aspas duplas. JSON não suporta funções, comentários ou valores undefined.

JSON.parse e JSON.stringify

JSON.parse converte uma string JSON em um objeto JavaScript. Se a string não for um JSON válido, lança um erro SyntaxError.

const jsonString = '{"nome":"Maria","idade":25}';
const obj = JSON.parse(jsonString);
console.log(obj.nome); // Maria

JSON.stringify converte um objeto JavaScript em uma string JSON. Aceita um segundo parâmetro opcional (replacer) para filtrar ou transformar propriedades, e um terceiro (space) para formatação.

const obj = { nome: 'Carlos', idade: 40, senha: '123456' };
const json = JSON.stringify(obj, ['nome', 'idade'], 2);
console.log(json);
// {
//   "nome": "Carlos",
//   "idade": 40
// }

O replacer pode ser uma função que recebe chave e valor, permitindo transformações como ocultar dados sensíveis.

Pegadinhas

Ao trabalhar com JSON, algumas armadilhas comuns incluem:

  • Chaves sem aspas duplas: Objetos JavaScript permitem chaves sem aspas, mas JSON exige aspas duplas. JSON.parse('{nome: "João"}') lança erro.
  • Valores undefined e funções: JSON.stringify ignora propriedades com valor undefined, funções e símbolos. Isso pode causar perda de dados inesperada.
  • Referências circulares: Se um objeto fizer referência a si mesmo (ex.: a.b = a), JSON.stringify lança TypeError.
  • Data e objetos especiais: Objetos Date são convertidos para strings ISO, e ao fazer parse, não são restaurados como Date. É necessário tratar manualmente.

Exemplo de referência circular:

const obj = {};
obj.self = obj;
JSON.stringify(obj); // TypeError: Converting circular structure to JSON

Uso com APIs

JSON é o formato padrão para comunicação com APIs REST. Ao fazer requisições com fetch, frequentemente usamos response.json() para extrair o corpo JSON, que internamente chama JSON.parse. Para enviar dados, usamos JSON.stringify no corpo da requisição.

Exemplo de GET:

fetch('https://api.exemplo.com/usuarios')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

Exemplo de POST:

const novoUsuario = { nome: 'Ana', email: 'ana@example.com' };
fetch('https://api.exemplo.com/usuarios', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(novoUsuario)
})
  .then(response => response.json())
  .then(data => console.log(data));

Boas Práticas

  • Sempre validar o JSON recebido antes de usar, especialmente de fontes externas.
  • Usar try/catch ao chamar JSON.parse para evitar que erros quebrem a aplicação.
  • Evitar armazenar dados sensíveis em JSON sem criptografia, pois é texto puro.
  • Utilizar o parâmetro space para formatar JSON em logs ou depuração.

Exercícios

  1. Dada a string JSON '{"nome":"Pedro","idade":28}', converta para objeto e imprima o nome.

    ✓ Resposta:
    const json = '{"nome":"Pedro","idade":28}';
    const obj = JSON.parse(json);
    console.log(obj.nome); // Pedro
  2. Converta o objeto { cidade: "Rio", populacao: 6000000 } para string JSON com formatação de 2 espaços.

    ✓ Resposta:
    const obj = { cidade: "Rio", populacao: 6000000 };
    const json = JSON.stringify(obj, null, 2);
    console.log(json);
    // {
    //   "cidade": "Rio",
    //   "populacao": 6000000
    // }
  3. Por que JSON.parse('{"a":1,}') lança um erro? Como corrigir?

    ✓ Resposta: JSON não permite vírgula após o último par chave-valor. A string correta seria '{"a":1}'.
  4. Usando fetch, faça uma requisição GET para https://jsonplaceholder.typicode.com/posts/1 e imprima o título do post.

    ✓ Resposta:
    fetch('https://jsonplaceholder.typicode.com/posts/1')
      .then(response => response.json())
      .then(data => console.log(data.title))
      .catch(err => console.error(err));
  5. Crie uma função que recebe um objeto e retorna uma string JSON, mas removendo propriedades com valor undefined.

    ✓ Resposta:
    function toJSON(obj) {
      return JSON.stringify(obj, (key, value) => {
        if (value === undefined) return undefined;
        return value;
      });
    }
    // Exemplo: toJSON({a: 1, b: undefined}) -> '{"a":1}'

Referências