Parsear JSON en JavaScript es algo que harás cientos de veces como desarrollador web.
Por suerte, JavaScript tiene soporte nativo — no hacen falta librerías. Pero hay más matices
en JSON.parse()
y JSON.stringify()
de los que la documentación deja ver. Vamos a verlo bien.
JSON.parse() — Convertir un string en objeto
JSON.parse() toma un string con formato JSON y lo convierte en un valor JavaScript.
Ese valor suele ser un objeto o array, pero también puede ser un string, número, booleano o null:
const jsonString = '{"name": "Alice", "age": 30, "active": true}';
const user = JSON.parse(jsonString);
console.log(user.name); // "Alice"
console.log(user.age); // 30
console.log(user.active); // true
console.log(typeof user); // "object"Fíjate en que la entrada debe ser un string. Un error frecuente es intentar parsear un valor que ya es
un objeto — JSON.parse({}) lanza un SyntaxError porque primero convierte el objeto a
"[object Object]", que no es JSON válido.
Envuelve siempre JSON.parse() en un try/catch
Esto es lo que nadie te cuenta: JSON.parse() lanza un
SyntaxError
si la entrada es JSON inválido. Si estás parseando datos de una API, input de usuario o un archivo, deberías siempre
manejar ese error. Una sola respuesta malformada puede tumbar tu app si no lo haces:
function safeParseJSON(str) {
try {
return { data: JSON.parse(str), error: null };
} catch (err) {
return { data: null, error: err.message };
}
}
const { data, error } = safeParseJSON('{"name": "Alice"}');
if (error) {
console.error('Invalid JSON:', error);
} else {
console.log(data.name); // "Alice"
}
// Handles bad input gracefully
const result = safeParseJSON('not json at all');
console.log(result.error); // "Unexpected token 'o', "not json "... is not valid JSON"Uso un wrapper como este en casi todos mis proyectos. Hace que el manejo de errores sea consistente y evita excepciones sin capturar que suban hasta tu UI.
JSON.stringify() — Convertir un objeto en string
JSON.stringify() hace lo contrario: convierte un valor JavaScript en un string JSON.
Lo usarás al enviar datos a una API, guardar en localStorage o escribir en un archivo:
const user = {
name: "Bob",
age: 25,
roles: ["admin", "editor"],
password: "secret123" // we'll handle this later
};
// Basic usage
const jsonString = JSON.stringify(user);
// '{"name":"Bob","age":25,"roles":["admin","editor"],"password":"secret123"}'
// Pretty-printed (great for logs and file output)
const prettyJson = JSON.stringify(user, null, 2);
console.log(prettyJson);
// {
// "name": "Bob",
// "age": 25,
// "roles": ["admin", "editor"],
// "password": "secret123"
// }El tercer argumento de JSON.stringify() es el nivel de indentación. Usar 2
o 4 te da una salida legible. El valor por defecto (sin tercer argumento) produce JSON compacto y minificado
— mejor para transmisión por red.
Lo que stringify() descarta silenciosamente
Esto les pica a los desarrolladores con frecuencia. JSON.stringify() omite silenciosamente ciertos valores
porque JSON no los soporta:
const data = {
name: "Alice",
greet: function() { return "hi"; }, // Functions → dropped
undef: undefined, // undefined → dropped
sym: Symbol("key"), // Symbols → dropped
nan: NaN, // NaN → null
inf: Infinity, // Infinity → null
date: new Date("2024-01-15") // Dates → ISO string
};
console.log(JSON.stringify(data, null, 2));
// {
// "name": "Alice",
// "nan": null,
// "inf": null,
// "date": "2024-01-15T00:00:00.000Z"
// }
// greet, undef, sym are GONEundefined y luego lo parseas,
esas claves estarán completamente ausentes. Esto puede causar bugs sutiles si tu código comprueba
obj.key === undefined más adelante.Obtener JSON de una API — El patrón del mundo real
En la práctica, la mayoría del parseo JSON ocurre al obtener datos de una API. La
Fetch API
lo hace sencillo — response.json() se encarga del parseo por ti:
async function getUser(userId) {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const user = await response.json(); // parses JSON automatically
return user;
} catch (err) {
console.error('Failed to fetch user:', err);
return null;
}
}
const user = await getUser(42);
if (user) {
console.log(`Hello, ${user.name}!`);
}response.json() es esencialmente JSON.parse(await response.text()).
También lanza un error si el cuerpo de la respuesta no es JSON válido, así que vale la pena capturarlo por separado
en código de producción.
Trabajar con datos JSON anidados
El JSON profundamente anidado es habitual en APIs reales. Así puedes navegarlo de forma segura sin que se rompa por claves inexistentes:
const apiResponse = {
"user": {
"profile": {
"address": {
"city": "Berlin"
}
}
}
};
// Unsafe — throws if any level is undefined
const city1 = apiResponse.user.profile.address.city; // "Berlin"
// Safe with optional chaining (ES2020+) — returns undefined instead of throwing
const city2 = apiResponse?.user?.profile?.address?.city; // "Berlin"
const zip = apiResponse?.user?.profile?.address?.zip; // undefined (not a crash)
// With a fallback using nullish coalescing
const country = apiResponse?.user?.profile?.address?.country ?? "Unknown";El encadenamiento opcional (?.)
y la coalescencia nula (??)
son características modernas de JavaScript — ambas parte de la
especificación ECMAScript desde 2020 — que hacen
que trabajar con estructuras JSON inciertas sea mucho más seguro. Úsalas sin miedo — están soportadas en todos
los navegadores modernos y Node.js 14+.
Las funciones replacer y reviver
Tanto JSON.stringify() como JSON.parse() aceptan un segundo argumento
que te permite personalizar la transformación. Son genuinamente útiles en escenarios reales:
// replacer: filter or transform values during stringify
const user = { name: "Alice", password: "s3cr3t", age: 30 };
const safe = JSON.stringify(user, ["name", "age"]); // only include these keys
// '{"name":"Alice","age":30}' — password is excluded
// reviver: transform values during parse
const dateJson = '{"name": "Alice", "createdAt": "2024-01-15T09:30:00Z"}';
const parsed = JSON.parse(dateJson, (key, value) => {
if (key === "createdAt") return new Date(value); // convert string to Date
return value;
});
console.log(parsed.createdAt instanceof Date); // true
console.log(parsed.createdAt.getFullYear()); // 2024El patrón reviver es especialmente útil para restaurar objetos Date después de
un viaje de ida y vuelta por JSON, ya que JSON no tiene un tipo fecha nativo.
Herramientas útiles
Al trabajar con JSON en proyectos JavaScript, estas herramientas ahorran tiempo: JSON Formatter para formatear respuestas minificadas de APIs, JSON Validator para comprobar errores de sintaxis, JSON Path para consultar campos específicos de payloads grandes, y JSON Escape cuando necesitas embeber JSON en un string. Para más profundidad, la referencia MDN de JSON es excelente.
Conclusión
JSON.parse() y JSON.stringify() son las dos funciones que necesitas.
Los hábitos clave que hay que adquirir: envolver siempre parse() en try/catch, usar encadenamiento opcional para
el acceso anidado, y saber qué descarta silenciosamente stringify(). Domina esos tres puntos y
manejarás el 99% de los escenarios JSON reales sin sorpresas.