¿Las claves JSON tienen que estar entre comillas?

236

Ejemplo: ¿Es válido el siguiente código contra la especificación JSON ?

{
    precision: "zip"
}

¿O debería usar siempre la siguiente sintaxis? (Y si es así, ¿por qué?)

{
    "precision": "zip"
}

Realmente no he encontrado algo sobre esto en las especificaciones JSON. Aunque usan citas alrededor de sus teclas en sus ejemplos.

christianvuerings
fuente

Respuestas:

147

Sí, necesitas comillas. Esto es para simplificarlo y evitar tener que tener otro método de escape para las palabras clave reservadas de JavaScript, es decir {for:"foo"}.

cobbal
fuente
12
Las citas no son más simples en muchas situaciones, como los archivos de configuración que se editan a mano. Lo desafortunado de que JSON se use (y se use incorrectamente) como un formato de intercambio casi universal es que tiene características específicas de Javascript.
miguel
12
Razón real: compruebe esta respuesta también - stackoverflow.com/questions/4201441/…
TechMaze
3
Tl; dr: no querían lidiar con la limitación de ECMAScript en palabras clave reservadas (sin comillas) como claves, por lo que solo necesitaban citar todas las claves.
BallpointBen
136

Estás en lo correcto al usar cadenas como la clave. Aquí hay un extracto de RFC 4627: la aplicación / json Media Type para JavaScript Object Notation (JSON)

2.2. Objetos

Una estructura de objeto se representa como un par de llaves entre cero o más pares de nombre / valor (o miembros). Un nombre es una cadena . Después de cada nombre, aparecen dos puntos, que separan el nombre del valor. Una coma simple separa un valor del siguiente nombre. Los nombres dentro de un objeto DEBEN ser únicos.

object = begin-object [ member *( value-separator member ) ] end-object

member = string name-separator value

[...]

2.5. Instrumentos de cuerda

La representación de cadenas es similar a las convenciones utilizadas en la familia C de lenguajes de programación. Una cadena comienza y termina con comillas. [...]

string = quotation-mark *char quotation-mark

quotation-mark = %x22 ; "

Lea el RFC completo aquí .

PatrikAkerstrand
fuente
11
Y para terminar el pensamiento, la sección 2.5 dice: A string begins and ends with quotation marks..
rakslice
13

De 2.2. Objetos

Una estructura de objeto se representa como un par de llaves entre cero o más pares de nombre / valor (o miembros). Un nombre es una cadena.

y de 2.5. Instrumentos de cuerda

Una cadena comienza y termina con comillas.

Entonces, diría que según el estándar: sí, siempre debe citar la clave (aunque algunos analizadores pueden ser más indulgentes)

Cebjyre
fuente
0

Ellos si. Pero si necesita lo contrario, revise JSON5 .

JSON5 es un superconjunto de JSON que permite la sintaxis de ES5, que incluye:

  • claves de propiedad sin comillas
  • cadenas de comillas simples, de escape y de varias líneas
  • formatos de números alternativos
  • comentarios
  • espacio en blanco extra

La implementación de referencia JSON5 ( json5paquete npm ) proporciona un JSON5objeto que tiene parsey stringifymétodos con los mismos argumentos y semánticas que el JSONobjeto incorporado .

Iñigo
fuente
-2

Como puede poner la notación punteada "parent.child" y no tiene que poner parent ["child"], que también es válido y útil, yo diría que ambas formas son técnicamente aceptables. Todos los analizadores deberían hacer ambas cosas bien. Si su analizador no necesita comillas en las claves, entonces probablemente sea mejor no ponerlas (ahorra espacio). Tiene sentido llamarlos cadenas porque eso es lo que son, y dado que los corchetes le dan la capacidad de usar valores para las teclas, esencialmente tiene mucho sentido no hacerlo. En Json puedes poner ...

>var keyName = "someKey";
>var obj = {[keyName]:"someValue"};

>obj
Object {someKey: "someValue"}

bien sin problemas, si necesita un valor para una clave y ninguno entre comillas no funcionará, por lo que si no lo hace, no puede, por lo que no lo hará "no necesita comillas en las claves". Incluso si es correcto decir que técnicamente son cadenas. La lógica y el uso argumentan lo contrario. Tampoco muestra oficialmente Object {"someKey": "someValue"} para obj en nuestro ejemplo ejecutado desde la consola de cualquier navegador.

El maestro james
fuente
2
Tanto la respuesta aceptada como el RFC que define JSON dicen que las comillas son obligatorias.
Keith Thompson el
Eso es cierto, pero vale la pena señalar que lógicamente no es necesario. Supongo que un resultado de JavaScript Object Notation de todas las consolas del navegador es incorrecto, y deberíamos decirle a alguien que lo arregle. Tal vez lo que una consola del navegador genera para un objeto no es JSON, por lo que tal vez JSON, como lo define la especificación, no es necesario ni se implementa de esa manera en la mayoría de los lugares. De todos modos, solo quería presentar el caso, que mira los hechos de una manera diferente. Realmente tal vez la especificación debería cambiarse, entonces, "Llaves citadas" simplemente no es necesario en ningún lugar que me importe personalmente. (Simplemente no se usa de esa manera en la práctica.)
Maestro James
2
Está mezclando tres cosas diferentes: JSON, literales de objetos de JavaScript y salida de consola de herramientas de desarrollador de navegador. Cuando escribe su objen la consola, el navegador muestra una representación legible del objeto. Puede mostrarlo como un objeto literal (como lo hizo en su ejemplo), o puede usar alguna otra representación, incluso una representación interactiva. Los literales de objetos de JavaScript no requieren comillas alrededor del nombre de una clave si la clave es un identificador válido y no una palabra reservada. Sin embargo, JSON siempre requiere comillas alrededor de los nombres clave.
Michael Geary
3
Como ejemplos adicionales, en lugar de escribir objen la consola, intente JSON.stringify(obj). Ahora verá una representación JSON válida del objeto, completa con el nombre clave entre comillas. Por el contrario, para ver si una cadena es JSON válida, intente JSON.parse(string). Si no se citan las claves, esto generará una excepción. Por ejemplo, JSON.parse('{"a":"b"}')tendrá éxito, pero JSON.parse('{a:"b"}')fracasará.
Michael Geary
1
OTOH, su uso de var obj = {[keyName]:"someValue"};es muy interesante! No sabía que podías hacer eso en un objeto JavaScript literal. Un poco de comprobación muestra que esto es algo nuevo en ES6: no se puede hacerlo en ES5.
Michael Geary