← Todos os artigos

Como serializar JSON com JSON.stringify

JSON.stringify converte um valor em string JSON. Aprenda os argumentos space e replacer, o hook toJSON e os valores que ele descarta silenciosamente ou nos quais lança.

JSON.stringify() converte um valor JavaScript em uma string JSON —— para enviar no corpo de uma requisição, salvar em um arquivo ou guardar em localStorage. Parece simples, mas seus três argumentos, o tratamento de valores especiais e o hook toJSON fazem os desenvolvedores tropeçarem o tempo todo. Este guia cobre tudo o que o JSON.stringify() faz, os equivalentes em outras linguagens e as armadilhas a evitar.

O que o JSON.stringify faz

Percorre um valor recursivamente e produz uma string JSON conforme a spec. A saída padrão é compacta, sem espaços extras:

const user = { name: "Ada", age: 36, active: true };

JSON.stringify(user);
// '{"name":"Ada","age":36,"active":true}'

Como sempre emite JSON válido, nunca monte strings JSON à mão com concatenação ou template literals —— fazer isso é a causa número um de erros [object Object] e erros de vírgulas finais.

Os três argumentos

JSON.stringify(value, replacer, space) aceita um valor e dois argumentos opcionais que a maioria nunca usa —— mas que são poderosos.

space —— pretty-print

O terceiro argumento controla a indentação. Passe um número para essa quantidade de espaços, ou uma string como '\t' para tabulações:

JSON.stringify(user, null, 2);
// {
//   "name": "Ada",
//   "age": 36,
//   "active": true
// }

É assim que se faz pretty-print de JSON no código —— veja Como formatar JSON. Omita o argumento (ou passe 0) para minificar; veja Como minificar JSON.

replacer —— filtrar e transformar

O segundo argumento pode ser um array de chaves a incluir ou uma função que transforma cada valor:

// Whitelist: só estas chaves sobrevivem
JSON.stringify(user, ['name', 'active']);
// '{"name":"Ada","active":true}'

// Função: mascara um campo, descarta outro
JSON.stringify(
  { name: "Ada", password: "secret", token: "abc" },
  (key, value) => {
    if (key === 'password') return '[REDACTED]';
    if (key === 'token') return undefined; // retornar undefined omite a chave
    return value;
  },
);
// '{"name":"Ada","password":"[REDACTED]"}'

O hook toJSON

Se um valor tem um método toJSON(), o JSON.stringify() o chama e serializa o valor retornado no lugar. É assim que objetos Date viram strings ISO automaticamente:

JSON.stringify({ when: new Date('2026-05-24T00:00:00Z') });
// '{"when":"2026-05-24T00:00:00.000Z"}'  ← Date.prototype.toJSON executado

// Defina seu próprio toJSON para serialização customizada
class Money {
  constructor(cents) { this.cents = cents; }
  toJSON() { return (this.cents / 100).toFixed(2); }
}
JSON.stringify({ price: new Money(1999) });
// '{"price":"19.99"}'

O que é descartado ou convertido

JSON só tem seis tipos, então valores JavaScript sem equivalente JSON são silenciosamente descartados ou convertidos —— fonte comum de bugs em round-trip:

Valor JavaScriptResultado do JSON.stringify
undefined (em objeto)chave omitida
undefined (em array)null
funçãoomitida (objeto) / null (array)
Symbolomitido
NaN, Infinitynull
Datestring ISO (via toJSON)
BigIntlança TypeError

Para a lista completa de como JSON difere de objetos JavaScript, veja JSON vs objetos JavaScript.

Armadilhas comuns

Referências circulares lançam

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

// Correção: um replacer que rastreia objetos vistos, ou reestruturar os dados

BigInt não é suportado

JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigInt

// Correção: converter para string antes, ou adicionar um replacer
JSON.stringify({ id: 9007199254740993n }, (k, v) =>
  typeof v === 'bigint' ? v.toString() : v
);

Inteiros grandes perdem precisão no round-trip

Números acima de 253 não podem ser representados exatamente. Se você stringificar e depois parsear um ID inteiro grande, ele pode mudar. Guarde esses IDs como strings.

APIs vizinhas: structuredClone, o reviver e Stable Stringify

  • structuredClone —— para cópias profundas em memória, não use JSON.parse(JSON.stringify(x)). O structuredClone lida com Date, Map, Set, ArrayBuffer e referências circulares nativamente, e é muito mais rápido.
  • O argumento reviver do JSON.parse é o espelho do replacer daqui. Use-os em par para round-trips sem perda em tipos que o JSON não modela —— ex.: codifique Date como string ISO no replacer e reidrate no reviver.
  • Bibliotecas de stable-stringify (ex.: json-stable-stringify, fast-json-stable-stringify) —— produzem a mesma string independentemente da ordem de inserção das chaves. Use-as quando a saída for hashada, assinada ou comparada como texto (veja RFC 8785 / JCS para a versão formal).

Stringify em outras linguagens

# Python
import json
json.dumps({"name": "Ada"})                       # compacto
json.dumps({"name": "Ada"}, indent=2)             # pretty
json.dumps({"name": "Ada"}, separators=(',', ':')) # minificado

// Go
import "encoding/json"
b, _ := json.Marshal(map[string]string{"name": "Ada"})

// Ruby
require 'json'
{ name: "Ada" }.to_json

Stringify de JSON no seu navegador

Precisa escapar um valor JSON para um literal de string —— para embutir em código, uma coluna de banco ou um comando de shell? A ferramenta JSON Stringify do fixjson faz isso instantaneamente, no seu navegador, sem enviar dados a nenhum servidor.

Perguntas frequentes

Como faço pretty-print com JSON.stringify?

Passe um terceiro argumento: JSON.stringify(value, null, 2) para 2 espaços ou '\t' para tabulações. Veja Como formatar JSON.

Por que o JSON.stringify descarta algumas das minhas propriedades?

Propriedades com valores undefined, função ou Symbol são omitidas porque o JSON não tem representação para elas. Use um replacer ou converta-as antes.

Como faço stringify de um valor com BigInt?

JSON.stringify() lança em BigInt. Forneça um replacer que chame .toString() sobre os bigints e parseie deliberadamente do outro lado.

Qual a diferença entre JSON.stringify e JSON.parse?

stringify transforma um valor em string JSON; parse transforma uma string JSON em valor. São inversos. Para armadilhas de parsing, veja Lidar com JSON quebrado em JavaScript.

Como faço JSON.stringify de um Map ou Set?

Por padrão, ambos serializam como "{}" —— um Map não tem propriedades próprias enumeráveis e um Set stringifica como objeto vazio. Converta-os antes para uma forma amigável a JSON (ou via um replacer):

// Map → array de pares [key, value] (round-trippable)
JSON.stringify([...myMap]);
// ou com um replacer:
JSON.stringify({ data: myMap }, (k, v) =>
  v instanceof Map ? Object.fromEntries(v) :
  v instanceof Set ? [...v] : v
);

De volta, reconstrua com new Map(arr) / new Set(arr) em um reviver do JSON.parse, já que JSON puro não tem tipos Map/Set.

Experimente agora