JSON em JavaScript: é texto, não objeto
O JSON (JavaScript Object Notation) é um formato de texto usado para troca de dados. Na aparência, ele lembra bastante um objeto literal de JavaScript, mas na prática é uma string — uma sequência de caracteres que você pode enviar pela rede, salvar em arquivo ou colar em um arquivo de configuração.
// Um objeto JavaScript — um valor vivo na memória.
const user = { name: "Rosa", age: 30 };
// JSON — uma string de texto que representa os mesmos dados.
const json = '{"name":"Rosa","age":30}';
Os dois são fáceis de confundir porque parecem iguais à primeira vista. O modelo mental que resolve isso: objetos vivem dentro do seu programa; JSON é como eles aparecem quando saem pra rua. A conversão entre os dois é feita por duas funções: JSON.stringify (objeto → string) e JSON.parse (string → objeto).
JSON.stringify: convertendo objeto em JSON no JavaScript
Transforme qualquer valor JavaScript na sua representação em JSON:
O resultado é uma string em linha única, sem espaços — compacta e perfeita para trafegar pela rede. O typeof não deixa dúvida: é string, não object.
Agora, quando você está debugando e quer algo mais legível, dá pra passar dois argumentos extras. O segundo é o replacer (já chego nele); passar null significa "inclui tudo". O terceiro controla a indentação:
Esse é o formato padrão de pretty print. Use 2 ou 4 espaços — é o que a maioria das ferramentas gera.
JSON.parse: convertendo JSON em objeto no JavaScript
Agora o caminho inverso: pega uma string JSON e devolve um valor JavaScript.
Depois de fazer o parse, você passa a lidar com um objeto normal — acesso por ponto, por colchetes, métodos de array, o pacote completo.
O JSON.parse é chato de agradar. Todos esses casos disparam um SyntaxError:
JSON.parse("{name: 'Rosa'}"); // chave sem aspas, aspas simples
JSON.parse('{"name": "Rosa",}'); // vírgula no final
JSON.parse("// a comment\n{}"); // comentários não são permitidos
JSON.parse(""); // string vazia
Sempre que a entrada vier de fora do seu programa — uma resposta do fetch, um arquivo ou algo digitado pelo usuário — envolva o parse em try/catch:
Valores que não sobrevivem ao ida e volta
O JSON suporta apenas seis tipos de valores: strings, números, booleanos, null, arrays e objetos simples. Qualquer outra coisa do JavaScript é descartada, transformada ou simplesmente quebra na hora de converter objeto em JSON.
O que acontece:
- Funções e
undefinedsão removidos silenciosamente dos objetos. Dentro de arrays, viramnull— arrays não podem ter "buracos" no JSON. - Objetos
Datesão serializados como string ISO pelo métodotoJSON. Ao fazer o parse, você recebe a string de volta, não umDate. BigIntlança umTypeError. Números em JSON não têm equivalente.Map,Sete referências circulares também não funcionam de cara.
A solução para recuperar Date no round-trip é a função reviver do JSON.parse:
O reviver é executado para cada par chave/valor e permite transformar os valores durante a conversão.
O replacer: filtrando o que será serializado
O segundo argumento do JSON.stringify permite controlar o que vai aparecer no resultado final. Passe um array de chaves para manter apenas as que você quer:
Ou passe uma função para aplicar qualquer lógica que quiser — remover campos, mascarar valores, transformar na hora:
Retornar undefined remove a chave. Qualquer outro valor retornado substitui o original.
Personalizando a serialização com toJSON
Quando um objeto tem um método toJSON, o JSON.stringify chama esse método e serializa o valor devolvido no lugar do objeto em si. É justamente assim que o Date define seu próprio formato — e você pode aproveitar o mesmo gancho nos seus objetos:
Ótimo para classes que precisam manter uma forma pública consistente, não importa quem esteja serializando.
Clone profundo (o truque antigo e o jeito melhor)
Por muito tempo, JSON.parse(JSON.stringify(obj)) foi a gambiarra clássica para fazer deep clone de um objeto simples:
Funciona — desde que o objeto só tenha valores compatíveis com JSON. Datas, Maps e funções quebram esse truque (veja os problemas de ida e volta logo acima).
O JavaScript moderno tem o structuredClone, que dá conta de Dates, Maps, Sets, typed arrays e até referências circulares:
Prefira structuredClone sempre que possível. Guarde o truque JSON.parse(JSON.stringify(...)) na manga para clonagens rápidas de dados simples.
Um exemplo real: fazendo fetch e parseando JSON
O lugar mais comum onde você vai esbarrar em JSON no JavaScript é em requisições HTTP. O fetch não faz o parse do JSON automaticamente — você precisa chamar .json() na resposta (o que, na prática, é um JSON.parse aplicado ao corpo da resposta):
Enviar JSON é o caminho inverso: passe o corpo pelo JSON.stringify e defina o header Content-Type.
await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Rosa", age: 30 }),
});
Esses dois padrões cobrem a grande maioria do trabalho com JSON no dia a dia.
A seguir: Optional Chaining
JSON já convertido costuma ter campos opcionais — um user.address.city que pode não existir, um response.data.items que pode estar ausente. Para acessar propriedades aninhadas sem quebrar a aplicação, existe o optional chaining (?.), que é o tema da próxima página.
Perguntas frequentes
Qual a diferença entre JSON e um objeto JavaScript?
JSON é um formato de texto — uma string que lembra um objeto literal do JavaScript, mas com regras bem mais rígidas. As chaves precisam estar entre aspas duplas, strings também usam aspas duplas, e os valores ficam restritos a strings, números, booleanos, null, arrays e objetos simples. Já um objeto JavaScript é um valor vivo na memória, que pode carregar funções, undefined, instâncias de Date e qualquer outra coisa.
Como converter um objeto JavaScript em JSON?
Basta chamar JSON.stringify(obj). Ele percorre o objeto e devolve uma string JSON. Se quiser formatar a saída, passe um terceiro argumento: JSON.stringify(obj, null, 2) gera o JSON indentado com 2 espaços. Importante: funções e valores undefined somem dos objetos e viram null quando aparecem dentro de arrays.
Por que JSON.parse está lançando erro?
O JSON.parse é rigoroso: vírgula sobrando no final, aspas simples, chaves sem aspas e comentários disparam um SyntaxError. Sempre que a string vier de uma requisição de rede, de um arquivo ou do usuário — ou seja, de qualquer lugar onde ela possa estar malformada — envolva a chamada em um try/catch.
O JSON.stringify preserva objetos Date?
Não. Um Date é convertido para uma string ISO, tipo "2026-01-15T10:30:00.000Z". Quando você faz JSON.parse de volta, recebe essa string, e não um objeto Date. Se precisar reconstruir a data, use o argumento reviver do JSON.parse para transformar strings ISO em instâncias de Date novamente.