← Todos los artículos

JSON vs objeto JavaScript: por qué no se permiten comillas simples

Muchos desarrolladores tratan los literales de objeto JS como JSON. No son lo mismo: comillas simples, claves sin comillas, comas finales, undefined, NaN — aquí cada diferencia con ejemplos.

Pegas lo que parecen datos válidos en un parser JSON y de inmediato lanza SyntaxError: Unexpected token '''. Los datos vienen de tu código JavaScript y se ven completamente razonables —— pero JSON y los object literals de JavaScript no son el mismo formato, y las diferencias importan más de lo que la mayoría de desarrolladores se da cuenta.

La respuesta corta: JSON no soporta comillas simples

Las comillas simples son simplemente ilegales en JSON. Cada string —— tanto keys como valores —— debe usar comillas dobles. Sin excepciones.

// ❌ JSON inválido —— strings con comillas simples
{ 'name': 'Ada Lovelace', 'active': true }

// ✅ JSON válido
{ "name": "Ada Lovelace", "active": true }

El error que verás en distintos entornos:

// Chrome / Node.js (V8)
SyntaxError: Unexpected token "'", "{'name':..." is not valid JSON

// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data

// Safari
SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSON

El mensaje de Safari es el más útil —— te dice exactamente cuál es el problema. Los otros solo reportan el carácter inesperado.

¿Por qué JSON requiere comillas dobles?

JSON fue definido por Douglas Crockford en 2001 y estandarizado como RFC 8259. La gramática especifica exactamente un delimitador de string: el carácter de comilla doble (U+0022). Las comillas simples sencillamente no están en la gramática.

La razón es simplicidad. JSON es un formato de intercambio de datos pensado para ser parseado por cualquier lenguaje, no solo JavaScript. Al mandar un único estilo de quoting, la spec elimina toda una clase de ambigüedad. Los parsers en Go, Python, Java, Rust y cualquier otro lenguaje implementan exactamente la misma regla.

JSON vs object literal de JavaScript: diferencias completas

Las comillas simples son solo una de varias diferencias. Aquí el panorama completo:

1. Las keys deben ser strings entre comillas dobles

// ❌ Object literal de JavaScript —— key desnuda, key con comillas simples
{ name: "Ada", 'score': 98 }

// ✅ JSON —— todas las keys son strings entre comillas dobles
{ "name": "Ada", "score": 98 }

Los object literals de JavaScript aceptan identificadores desnudos, strings entre comillas simples y strings entre comillas dobles como keys. JSON solo acepta strings entre comillas dobles.

2. Sin comas finales

// ❌ JSON inválido
{ "name": "Ada", "score": 98, }
//                            ^ coma final

// ✅ JSON válido
{ "name": "Ada", "score": 98 }

JavaScript moderno permite explícitamente comas finales. JSON no —— mira nuestra guía completa sobre comas finales en JSON.

3. Sin comentarios

// ❌ JSON inválido
{
  // perfil de usuario
  "name": "Ada"
}

// ✅ JSON no tiene sintaxis de comentarios
{ "name": "Ada" }

JSON no tiene ninguna sintaxis de comentarios. Si necesitas comentarios en archivos de configuración, considera el formato JSONC (JSON-with-Comments), soportado por la configuración de VS Code, el tsconfig.json de TypeScript y varios parsers de archivos de config.

4. Sin undefined, funciones ni symbols

// Objeto JavaScript —— acepta valores no serializables
const obj = {
  fn: () => 42,         // función
  sym: Symbol('id'),    // Symbol
  val: undefined,       // undefined
};

// JSON.stringify los descarta o convierte silenciosamente
JSON.stringify(obj);
// → '{}'   (las tres propiedades desaparecen o se vuelven null)

JSON soporta exactamente seis tipos de valor: string, number, boolean (true/false), null, object y array. Funciones, Symbols y undefined no tienen representación en JSON. JSON.stringify() descarta silenciosamente las propiedades de objeto con esos valores y los convierte a null dentro de arrays.

5. Sin NaN ni Infinity

JSON.stringify({ ratio: NaN, limit: Infinity });
// → '{"ratio":null,"limit":null}'
// NaN e Infinity se vuelven null —— ¡silenciosamente!

JSON.parse('{"ratio": NaN}');
// → SyntaxError: Unexpected token 'N'

NaN e Infinity son valores numéricos válidos en JavaScript pero no son parte de la especificación de números de JSON. JSON.stringify() los convierte a null al salir; JSON.parse() los rechaza al entrar. Esta asimetría es una fuente común de bugs sutiles.

6. Números: sin hex, sin ceros iniciales, sin +

// ❌ JSON inválido
{ "flags": 0xFF, "code": 007, "delta": +1.5 }

// ✅ JSON válido
{ "flags": 255, "code": 7, "delta": 1.5 }

Los números JSON deben ser decimales, no pueden empezar con un signo + explícito, y no pueden tener ceros iniciales (excepto el único dígito 0 antes de un punto decimal). Los literales hexadecimales y octales no son JSON válido.

7. Sin strings multilínea

// ❌ JSON inválido —— nueva línea literal en string
{ "bio": "Line one
Line two" }

// ✅ Usa la secuencia de escape
{ "bio": "Line one\nLine two" }

8. Keys computadas, keys Symbol y shorthand de métodos

Tres funciones más exclusivas de JS que parecen JSON pero no tienen equivalente:

// ❌ Nombres de propiedad computados —— evaluados, no literales
const k = "id";
const obj = { [k]: 1, [`user_${k}`]: 1 };
// JSON no tiene expresiones; la key debe ser un string literal entre comillas dobles.

// ❌ Keys Symbol —— descartadas silenciosamente por JSON.stringify
const tag = Symbol('tag');
JSON.stringify({ [tag]: 'admin' });  // → '{}'

// ❌ Shorthand de métodos —— las funciones se descartan/omiten
const obj = { greet() { return 'hi'; } };
JSON.stringify(obj);  // → '{}'

Si necesitas alguna de estas, serializa una proyección con forma de JSON de tu objeto —— JSON.stringify() solo produce keys string y los seis tipos de valor JSON.

Una cheatsheet rápida de conversión

Object literal de JavaScriptEquivalente JSON válido
{ name: "Ada" }{"name":"Ada"}
{ 'name': 'Ada' }{"name":"Ada"}
{ a: 1, }{"a":1}
{ val: undefined }{} (propiedad descartada)
{ n: NaN }{"n":null}
{ n: Infinity }{"n":null}
{ fn: () => 1 }{} (propiedad descartada)
0xFF255

La forma más segura de convertir un objeto JS a JSON

Nunca intentes convertir un objeto JavaScript a JSON editando comillas a mano. Usa JSON.stringify() —— maneja correctamente todos los casos límite:

const obj = { name: 'Ada', score: 98, active: true };

// Compacto
JSON.stringify(obj);
// → '{"name":"Ada","score":98,"active":true}'

// Pretty-print con indent de 2 espacios
JSON.stringify(obj, null, 2);
// → '{
  "name": "Ada",
  "score": 98,
  "active": true
}'

El segundo argumento de JSON.stringify() es un replacer —— puedes pasar un array de nombres de key para incluir solo esas propiedades, o una función para transformar valores:

// Solo incluir keys específicas
JSON.stringify(obj, ['name', 'score'], 2);
// → '{
  "name": "Ada",
  "score": 98
}'

// Replacer custom —— convertir undefined a null
JSON.stringify({ a: 1, b: undefined }, (key, value) =>
  value === undefined ? null : value
);
// → '{"a":1,"b":null}'

Cuando recibes un object literal JS como string

A veces recibes datos que parecen JSON pero en realidad son un object literal de JavaScript —— quizá de un archivo de log, una herramienta de debugging, o una API que no seguía la spec. En ese caso JSON.parse() fallará y tienes dos opciones:

  • Usar un parser de reparación —— convierte comillas simples a dobles, quita comas finales, mete entre comillas las keys desnudas y maneja todas las demás diferencias automáticamente. Es el enfoque más seguro para input no confiable.
  • Usar eval() o Function() —— técnicamente funciona para JavaScript válido, pero es un grave riesgo de seguridad si la fuente no es totalmente confiable. Nunca hagas esto con input provisto por usuarios.

Preguntas frecuentes

¿JSON soporta comillas simples?

No. La gramática de JSON (RFC 8259) define exactamente un delimitador de string —— la comilla doble. Tanto keys como valores deben usar comillas dobles; las comillas simples lanzan un SyntaxError.

¿Cuál es la diferencia entre JSON y un objeto JavaScript?

JSON es un formato de texto estricto; un object literal de JavaScript es código permisivo. JS permite comillas simples, keys sin comillas, comas finales, comentarios, undefined, NaN, funciones y números hex —— ninguno de los cuales es JSON válido. Mira la cheatsheet completa arriba y el primer en ¿Qué es JSON?

¿Cómo convierto un objeto JavaScript a JSON?

Usa JSON.stringify() —— nunca edites comillas a mano. Maneja todo caso límite, descartando valores no serializables y escapando strings correctamente.

¿Por qué no puedo usar eval() para parsear un object literal JS?

eval() ejecuta código arbitrario, así que es un grave riesgo de seguridad en input no confiable. Usa un parser de reparación (o JSON Fix) para convertir un object literal JS a JSON válido de forma segura.

Arregla las comillas simples al instante

Si tienes un object literal de JavaScript que necesitas convertir a JSON válido ya mismo, JSON Fix maneja la conversión automáticamente. Convierte comillas simples a dobles, mete entre comillas las keys desnudas, quita comas finales y arregla todas las demás diferencias listadas arriba —— en tu navegador, sin datos enviados a ningún servidor.