JSON.stringify() convierte un valor JavaScript en una cadena JSON —— para enviarlo en el cuerpo de una petición, guardarlo en un fichero o almacenarlo en localStorage. Parece simple, pero sus tres argumentos, su manejo de valores especiales y el hook toJSON hacen tropezar a los desarrolladores sin cesar. Esta guía cubre todo lo que hace JSON.stringify(), los equivalentes en otros lenguajes y las trampas a evitar.
Qué hace JSON.stringify
Recorre un valor recursivamente y produce una cadena JSON conforme a la especificación. La salida por defecto es compacta, sin espacios adicionales:
const user = { name: "Ada", age: 36, active: true };
JSON.stringify(user);
// '{"name":"Ada","age":36,"active":true}'Como siempre emite JSON válido, nunca construyas cadenas JSON a mano con concatenación o template literals —— hacerlo es la causa número uno de errores [object Object] y errores de comas finales.
Los tres argumentos
JSON.stringify(value, replacer, space) acepta un valor y dos argumentos opcionales que la mayoría no usa nunca —— pero son potentes.
space — — pretty-print
El tercer argumento controla la indentación. Pasa un número para esos espacios, o una cadena como '\t' para tabuladores:
JSON.stringify(user, null, 2);
// {
// "name": "Ada",
// "age": 36,
// "active": true
// } Así es como se hace pretty-print de JSON en código —— ver Cómo formatear JSON. Omite el argumento (o pasa 0) para minificar; ver Cómo minificar JSON.
replacer —— filtrar y transformar
El segundo argumento puede ser un array de claves a incluir o una función que transforma cada valor:
// Lista blanca: solo sobreviven estas claves
JSON.stringify(user, ['name', 'active']);
// '{"name":"Ada","active":true}'
// Función: enmascara un campo, descarta otro
JSON.stringify(
{ name: "Ada", password: "secret", token: "abc" },
(key, value) => {
if (key === 'password') return '[REDACTED]';
if (key === 'token') return undefined; // devolver undefined omite la clave
return value;
},
);
// '{"name":"Ada","password":"[REDACTED]"}'El hook toJSON
Si un valor tiene un método toJSON(), JSON.stringify() lo llama y serializa el valor devuelto en su lugar. Por eso los objetos Date se convierten automáticamente en cadenas ISO:
JSON.stringify({ when: new Date('2026-05-24T00:00:00Z') });
// '{"when":"2026-05-24T00:00:00.000Z"}' ← Date.prototype.toJSON ejecutado
// Tu propio toJSON para serialización personalizada
class Money {
constructor(cents) { this.cents = cents; }
toJSON() { return (this.cents / 100).toFixed(2); }
}
JSON.stringify({ price: new Money(1999) });
// '{"price":"19.99"}'Qué se descarta o se convierte
JSON solo tiene seis tipos, así que los valores JavaScript sin equivalente JSON se descartan en silencio o se convierten —— fuente habitual de bugs en round-trip:
| Valor JavaScript | Resultado de JSON.stringify |
|---|---|
undefined (en objeto) | clave omitida |
undefined (en array) | null |
| función | omitida (objeto) / null (array) |
Symbol | omitido |
NaN, Infinity | null |
Date | cadena ISO (vía toJSON) |
BigInt | lanza TypeError |
Para la lista completa de cómo difiere JSON de los objetos JavaScript, ver JSON vs objetos JavaScript.
Trampas comunes
Las referencias circulares lanzan
const a = {};
a.self = a;
JSON.stringify(a);
// TypeError: Converting circular structure to JSON
// Solución: un replacer que rastree objetos vistos, o reestructura los datosBigInt no es compatible
JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigInt
// Solución: convertir a string primero, o añadir un replacer
JSON.stringify({ id: 9007199254740993n }, (k, v) =>
typeof v === 'bigint' ? v.toString() : v
);Los enteros grandes pierden precisión en el round-trip
Los números por encima de 253 no pueden representarse de forma exacta. Si stringifyas y luego parseas un ID entero grande, puede cambiar. Guarda esos IDs como cadenas.
APIs cercanas: structuredClone, el reviver y Stable Stringify
structuredClone—— para copias profundas en memoria, no usesJSON.parse(JSON.stringify(x)).structuredClonemanejaDate,Map,Set,ArrayBuffery referencias circulares de forma nativa y es mucho más rápido.- El argumento
reviverdeJSON.parsees el reflejo delreplacerde aquí. Úsalos en pareja cuando necesites round-trip sin pérdida para tipos que JSON no modela —— p. ej. codificaDatecomo cadena ISO enreplacery rehidrátalo enreviver. - Librerías stable-stringify (p. ej.
json-stable-stringify,fast-json-stable-stringify) —— producen la misma cadena independientemente del orden de inserción de las claves. Úsalas cuando la salida se hashee, firme o compare como texto (ver RFC 8785 / JCS para la versión formal).
Stringify en otros lenguajes
# 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_jsonStringify de JSON en tu navegador
¿Necesitas escapar un valor JSON a un literal de cadena —— para incrustarlo en código, una columna de BD o un comando de shell? La herramienta JSON Stringify de fixjson lo hace al instante, en tu navegador, sin enviar datos a ningún servidor.
Preguntas frecuentes
¿Cómo hago pretty-print con JSON.stringify?
Pasa un tercer argumento: JSON.stringify(value, null, 2) para 2 espacios o '\t' para tabuladores. Ver Cómo formatear JSON.
¿Por qué JSON.stringify descarta algunas de mis propiedades?
Las propiedades con valores undefined, función o Symbol se omiten porque JSON no tiene representación para ellos. Usa un replacer o conviértelos antes.
¿Cómo hago stringify de un valor con BigInt?
JSON.stringify() lanza con BigInt. Proporciona un replacer que llame a .toString() sobre los valores bigint y parsealos deliberadamente al otro lado.
¿Cuál es la diferencia entre JSON.stringify y JSON.parse?
stringify convierte un valor en una cadena JSON; parse convierte una cadena JSON en un valor. Son inversos. Para trampas del parseo, ver Manejar JSON roto en JavaScript.
¿Cómo hago JSON.stringify de un Map o Set?
Por defecto ambos se serializan como "{}" —— un Map no tiene propiedades propias enumerables y un Set se stringifya como objeto vacío. Conviértelos antes a una forma JSON-friendly (o vía un replacer):
// Map → array de pares [key, value] (round-trippable)
JSON.stringify([...myMap]);
// o con un replacer:
JSON.stringify({ data: myMap }, (k, v) =>
v instanceof Map ? Object.fromEntries(v) :
v instanceof Set ? [...v] : v
); De vuelta, reconstruye con new Map(arr) / new Set(arr) en un reviver de JSON.parse, ya que el JSON puro no tiene tipos Map/Set.
Pruébalo ahora
- JSON Stringify —— escapa un valor JSON a un literal de cadena, en tu navegador
- Cómo formatear JSON —— pretty-print con el argumento
space - Cómo minificar JSON —— la forma compacta y cuándo ayuda
- ¿Qué es JSON? —— los seis tipos que puede producir stringify