JavaScript JSON
Aprende a trabajar con JSON en JavaScript: parsear y serializar datos, usar revivers y replacers, formatear la salida, copiar objetos en profundidad y manejar fechas y errores comunes.
JavaScript Object Notation (JSON) es la columna vertebral del intercambio de datos en la web. Casi todas las APIs que llamas devuelven JSON, casi todos los archivos de configuración que lees probablemente son JSON, y cada vez que el navegador se comunica con un servidor, JSON suele ser el formato utilizado. Esta guía cubre todo lo que necesitas para trabajar con JSON con confianza en JavaScript: la sintaxis, los dos métodos principales (JSON.parse y JSON.stringify), cómo formatear y filtrar la salida, cómo manejar fechas y copias profundas, y los errores más comunes que surgen en producción.
Qué es JSON y por qué importa
JSON es un formato de datos ligero basado en texto, fácil de leer y escribir para las personas, y fácil de parsear y generar para las máquinas. Es independiente del lenguaje — aunque su sintaxis está tomada de JavaScript (Standard ECMA-262), prácticamente todos los lenguajes (Python, Java, C#, Go, Rust, PHP) pueden leerlo y escribirlo. Esa universalidad es exactamente la razón por la que se convirtió en el formato predeterminado para las REST APIs, los archivos de configuración (package.json, tsconfig.json) y localStorage.
Lo fundamental que debes entender: JSON es una cadena de texto, no un object. Una cadena JSON solo se convierte en un objeto JavaScript utilizable después de parsearla, y un objeto JavaScript solo se convierte en JSON después de serializarlo. La mayor parte del trabajo con JSON consiste en moverse entre estos dos estados.
Sintaxis básica de JSON
La sintaxis de JSON es un subconjunto estricto de la sintaxis de objetos literales de JavaScript:
- Los datos se escriben como pares
"clave": valor - Los pares se separan con comas
- Las llaves
{}contienen objects, los corchetes[]contienen arrays - Las claves deben ser strings entre comillas dobles (las comillas simples y las claves sin comillas son inválidas)
- Los valores pueden ser un string, un número, un boolean,
null, un object o un array — pero noundefined, una función ni unDate
{
"name": "John",
"age": 30,
"isDeveloper": true,
"languages": ["JavaScript", "Python", "Rust"]
}Parsear JSON con JSON.parse()
JSON.parse() convierte una cadena JSON en un objeto JavaScript (o array, número, etc.) que puedes leer y manipular. En código real — especialmente cuando el JSON proviene de una petición de red o de la entrada del usuario — envuélvelo siempre en un try...catch, porque un JSON malformado lanza un SyntaxError.
Acceder a datos anidados
El JSON parseado se comporta como cualquier otro object, por lo que puedes acceder a los valores anidados con la notación de punto o de corchetes. Esto es lo más habitual al trabajar con la respuesta de una API.
Transformar valores con un reviver
JSON.parse() acepta una función reviver opcional como segundo argumento. Se invoca para cada par clave/valor, y lo que devuelve se convierte en el valor final — muy útil para convertir tipos durante el parseo. Un uso clásico es restaurar objetos Date (JSON no tiene tipo de fecha, por lo que las fechas llegan como strings).
Serializar objetos con JSON.stringify()
JSON.stringify() hace lo contrario: convierte un valor JavaScript en una cadena JSON, lista para enviar por la red o guardar en el almacenamiento.
Formatear con sangría
El tercer argumento controla el espaciado. Pasa un número (espacios) o una cadena para producir JSON legible con sangría — útil para logs, archivos de configuración y depuración.
Filtrar propiedades con un replacer
El segundo argumento es un replacer. Como array de claves permite seleccionar qué propiedades conservar — una forma rápida de eliminar campos sensibles como contraseñas antes de enviar los datos.
Como función, el replacer se invoca para cada clave y permite transformar u omitir valores. Devolver undefined desde ella elimina esa propiedad.
Serialización personalizada con toJSON
Puedes controlar cómo se serializa un object específico dándole un método toJSON(). Cuando JSON.stringify() encuentra un object con este método, llama a toJSON() y serializa lo que devuelve. (Así es exactamente como los objetos Date producen cadenas ISO — tienen un toJSON integrado.)
Lo que stringify omite silenciosamente
JSON.stringify() es deliberadamente imperfecto. Saber qué omite evita errores confusos:
- Los valores
undefined, las funciones y los valoresSymbolse omiten de los objects (y se convierten ennulldentro de los arrays). - Los objetos
Datese convierten en cadenas ISO (mediante sutoJSON). NaNeInfinityse convierten ennull.BigIntlanza unTypeError.- Las referencias circulares lanzan un
TypeError.
Técnicas avanzadas y patrones comunes
Más allá de los dos métodos principales, el trabajo diario con JSON implica copias profundas, manejo de fechas y procesamiento de arrays de registros.
Copiar objetos en profundidad
El truco JSON.parse(JSON.stringify(obj)) crea una copia profunda — un clon cuyos objects anidados son completamente independientes del original, por lo que mutar uno nunca afecta al otro.
Es rápido y no requiere dependencias externas, pero hereda todas las limitaciones de stringify: elimina funciones, undefined y Symbols, convierte los Dates en strings y lanza un error con referencias circulares. Para una copia fiel, prefiere el integrado structuredClone(), que maneja fechas, maps, sets y ciclos.
Trabajar con fechas
JSON no tiene tipo de fecha, por lo que las fechas viajan como cadenas ISO 8601. JSON.stringify las escribe automáticamente, pero al parsear obtienes una cadena simple de vuelta — debes reconstruir el objeto Date tú mismo, ya sea con new Date(...) o con un reviver (como se muestra anteriormente).
Procesar arrays de registros
Las respuestas de las APIs suelen ser arrays de objects. Tras el parseo, los métodos estándar de array (forEach, map, filter) hacen el resto.
JSON y el navegador: fetch y localStorage
Dos lugares cotidianos donde aparece JSON:
fetch:response.json()lee el cuerpo y lo parsea por ti, por lo que raramente llamas directamente aJSON.parseen un resultado de fetch —const data = await response.json();. Consulta la guía de la Fetch API.localStorage: almacena solo strings, así que serializa al guardar y parsea al recuperar:localStorage.setItem('user', JSON.stringify(user))y luegoJSON.parse(localStorage.getItem('user')).
Conclusión
JSON es el formato con el que más trabajarás como desarrollador de JavaScript, y en realidad se reduce a dos métodos: JSON.parse() para convertir una cadena en un valor utilizable, y JSON.stringify() para convertir un valor de vuelta en una cadena. Añade los argumentos reviver y replacer para la conversión de tipos y el filtrado, la sangría para una salida legible, y toJSON para una serialización personalizada, y podrás manejar casi cualquier tarea de intercambio de datos.
Ten en cuenta los casos límite de pérdida de información — los undefined/funciones descartados, las fechas serializadas como strings y los errores de referencias circulares — y recurre a structuredClone() cuando necesites una copia verdadera en lugar de un viaje de ida y vuelta por JSON. Con estas herramientas podrás mover datos con confianza entre tu aplicación, el servidor y el almacenamiento del navegador.