¿Puedes usar una coma final en un objeto JSON?

Al generar manualmente un objeto o matriz JSON, a menudo es más fácil dejar una coma final en el último elemento del objeto o matriz. Por ejemplo, el código para la salida de una matriz de cadenas podría parecerse (en un pseudocódigo similar a C ++):

s.append("[");
for (i = 0; i < 5; ++i) {
    s.appendF("\"%d\",", i);
}
s.append("]");

dándote una cadena como

[0,1,2,3,4,5,]

Está permitido?

321
Curiosamente (o horripilantemente) en IE 8 acabo de encontrar que la alerta ([1, 2, 3,] .length) mostrará "4".
agregado el autor Daniel Earwicker, fuente
También me lo estaba preguntando, así que es una pregunta perfectamente razonable.
agregado el autor hoju, fuente
En respuesta a la idea de usar SO como un marcador social para preguntas de programación comunes: ¿qué podría estar mal al agregar contenido que inevitablemente traerá más programadores (y su experiencia) al sitio?
agregado el autor dclowd9901, fuente
Como Jeff dijo, creo que está perfectamente bien usar SO como un "cuaderno" de cosas que tienes que pasar un tiempo mirando hacia arriba. Claro, esto está en el extremo simple de ese tipo de elementos, pero todavía creo que es apropiado, especialmente porque los diferentes motores de JavaScript se ocuparán de esto de manera diferente.
agregado el autor pkaeding, fuente
@DanielEarwicker: irrelevante, ya que eso no es JSON.
agregado el autor Lightness Races in Orbit, fuente
Si JSON no es para motores de Javascript, ¿por qué se llama "JavaScript Object Notation"?
agregado el autor James Curran, fuente
Era algo que necesitaba buscar en la web hace unos días. No vi una respuesta aquí en SO, así que al seguir la misión del sitio, hice la pregunta y la respondí para que otros pudieran encontrarla. Esto es algo que Jeff dijo explícitamente que quería hacer aquí.
agregado el autor Ben Combee, fuente
¡Gracias! No quería eliminar la etiqueta yo mismo.
agregado el autor Ben Combee, fuente
Pero una cosa más: ¿por qué OP escribe MANUALMENTE JSON? Eso es un anti-patrón claro: siempre se debe usar una biblioteca para generar JSON o convertir a/desde la estructura de objetos que tiene el lenguaje. Usar la concatenación de cadenas es solo pedir problemas; no solo para comas, sino para codificar, escapar, anidar incorrectamente. Es exactamente tan malo como usar manipulación de cadenas o expresiones regulares para XML.
agregado el autor StaxMan, fuente
Con algo tan básico que la respuesta se encuentra al observar las especificaciones oficiales, esto suena más como buscar puntos que proporcionar respuestas útiles a problemas no resueltos. Lo siento amigo.
agregado el autor eyelidlessness, fuente
Por lo que vale, mi queja no fue que la pregunta sea simple (con mucho gusto he respondido varias preguntas simples aquí), sino que parecía (a primera vista) ser una pregunta dirigida a los puntos de reputación de los juegos. También notará que concedí que la pregunta es válida después de un debate.
agregado el autor eyelidlessness, fuente
Eliminé la etiqueta de pregunta ideada porque es evidente que esto no es tan conocido como debería ser, a pesar del hecho de que está explícitamente detallado en la especificación oficial.
agregado el autor eyelidlessness, fuente
Porque los literales de objetos Javascript inspiraron el formato. ¿No crees que está diciendo que los motores JS están comenzando a tener capacidades JSON integradas? simonwillison.net/2006/Dec/20/json Pero JSON tiene muchas restricciones, no impuesto por JS, ej. Los literales de objeto JS no requieren claves entrecomilladas.
agregado el autor eyelidlessness, fuente
Además, los motores JS que lo tratan de manera diferente se derivan del hecho de que JS no comprende (actualmente) JSON y simplemente lo trata como un objeto/matriz literal. La diferencia es una diferencia en el tratamiento del motor de los literales objeto/matriz, que no son los mismos que JSON.
agregado el autor eyelidlessness, fuente
JSON no es para motores de Javascript, es un formato universal de intercambio de datos. No hay lugar para error en la respuesta a la pregunta, porque está claramente especificado.
agregado el autor eyelidlessness, fuente
Si te sirve de consuelo, no devolví el voto, solo agregué la etiqueta porque pensé que era apropiado.
agregado el autor eyelidlessness, fuente
Acordé que esta es una buena pregunta para publicar. Llegué aquí buscando en Google la pregunta.
agregado el autor fool4jesus, fuente

14 Respuestas

Lamentablemente, la especificación JSON no permite una coma al final. Hay algunos navegadores que lo permitirán, pero en general debe preocuparse por todos los navegadores.

En general intento volver el problema y agregar la coma antes del valor real, por lo que terminas con un código que se ve así:

s.append("[");
for (i = 0; i < 5; ++i) {
  if (i) s.append(",");//add the comma only if this isn't the first entry
  s.appendF("\"%d\"", i);
}
s.append("]");

Esa línea adicional de código en tu ciclo for es difícil de usar ...

Another alternative I've used when output a structure to JSON from a dictionary of some form is to always append a comma after each entry (as you are doing above) and then add a dummy entry at the end that has not trailing comma (but that is just lazy ;->).

No funciona bien con una matriz desafortunadamente.

179
agregado
Es realmente una pena que ECMA5 especifique huellas, pero JSON no.
agregado el autor FlavorScape, fuente
gran consejo acerca de agregar una entrada ficticia al final!
agregado el autor dcsan, fuente
Sí, esa línea adicional no es cara, pero es una molestia, sin embargo.
agregado el autor René Nyffenegger, fuente
Este enfoque funciona para bucles forzados indexados. ¿Qué tal ... en los lazos de estilo? ¿Hay una manera elegante?
agregado el autor sam, fuente
Si le gusta el código ofuscado, puede evitar el agregado adicional así: s.appendF (& ", \"% d \ "" [! I], i); . Podría simplificarlo a "..." +! I , pero el compilador puede advertir acerca de la aritmética de cadenas.
agregado el autor Marcelo Cantos, fuente
Buena respuesta. proporcione "prueba" (un enlace a documentos, especificaciones, etc.) de su respuesta.
agregado el autor chharvey, fuente
Bueno, ahora tengo una tarea para escribir un árbol de sintaxis en forma de JSON mientras está generado por un autómata de pila. No puedo usar este truco desafortunadamente.
agregado el autor Calmarius, fuente
¿Hay alguna forma de que Firefox se comporte como IE en este aspecto y genere un error o al menos una advertencia cuando se encuentra una coma final? Me desarrollo principalmente en Firefox, por lo que sería bueno ser notificado de este problema lo antes posible.
agregado el autor Michael Butler, fuente
Se actualizó la respuesta para responder explícitamente a la pregunta. Estoy de acuerdo, mi respuesta inicial saltó el explícito, "no".
agregado el autor brianb, fuente
Esa línea extra de código puede ser complicada cuando se trata de propiedades. Puede que tengas toneladas de if s solo para evitar esa pequeña coma estúpida. Sobre el YMMV costoso, vea esto, por ejemplo, jsfiddle.net/oriadam/mywL9384 Aclaración: Su solución es excelente , Odio las especificaciones que prohíben una coma final.
agregado el autor oriadam, fuente
Empecé a utilizar este formato en todos mis códigos JS (coma antes del elemento en la misma línea) exactamente por este motivo. Hace que las comas finales adicionales sean mucho más fáciles de detectar y ahorra mucho tiempo. Es molesto, ojalá hubiera una opción para lanzar un error para esto con Firefox (ya que eso ayudaría con la depuración).
agregado el autor rocketmonkeys, fuente

No. La especificación JSON, como se mantiene en http://json.org , no permite comas al final. Por lo que he visto, algunos analizadores pueden permitirlos en silencio al leer una cadena JSON, mientras que otros arrojarán errores. Para la interoperabilidad, no debe incluirlo.

El código anterior podría reestructurarse, ya sea para eliminar la coma al agregar el terminador de la matriz o para agregar la coma antes de los elementos, omitiendo esa para la primera.

113
agregado
Y esta es la respuesta correcta a la pregunta.
agregado el autor cdiggins, fuente
ECMA 262 Parece definirlo en la sección 11.1.5-Inicializador de objetos. Si esto es bueno o no, parece estar en la especificación.
agregado el autor Zero Distraction, fuente
@ZeroDistraction: ECMA262 define ECMAscript (también conocido como javascript) que es un lenguaje de programación como Perl o ruby o C ++ o Java. JSON es un formato de datos como xml o CSV o YAML. No són la misma cosa. JSON no existe en EXMA262, pero la sintaxis de la que se deriva lo hace y se llama notación literal del objeto (ON en JSON).
agregado el autor slebetman, fuente
Ser válido ECMAScript no significa necesariamente que un documento sea válido JSON - JSON generalmente se define en RFC 4627 , y esa especificación no permite la coma final.
agregado el autor Tim Gilbert, fuente

Simple, barato, fácil de leer, y siempre funciona independientemente de las especificaciones.

$delimiter = '';
for ....  {
    print $delimiter.$whatever
    $delimiter = ',';
}

La asignación redundante a $ delim es un precio muy bajo para pagar. También funciona igual de bien si no hay un bucle explícito, sino fragmentos de código separados.

96
agregado
Eso es lo que suelo hacer en situaciones como esta; Siento que la asignación adicional se compensa con creces eliminando la condición necesaria para agregar la coma antes del valor en el enfoque alternativo ( stackoverflow.com/ a/201856/8946 ).
agregado el autor Lawrence Dol, fuente
Además, es mejor incluir el alcance del separador: for (let ..., sep = ""; ...; sep = ",") {...
agregado el autor Lawrence Dol, fuente
No me gusta esta solución, ya que hay otra variable que contamina mi alcance. Uno if es más fácil de comprender. Pero gracias por compartir
agregado el autor Ich, fuente

Las comillas finales están permitidas en JavaScript, pero no funcionan en IE. Las especificaciones JSON sin versión de Douglas Crockford no las permitían, y debido a que no tenían una versión moderna, se suponía que esto no iba a cambiar. La especificación ES5 JSON les permitió una extensión, pero los RFC 4627 de Crockford no funcionaron, y ES5 revertió para rechazarlos. Firefox hizo lo mismo. Internet Explorer es por lo que no podemos tener cosas agradables.

15
agregado
Acabo de probarlos en IE 11 sin ningún problema. ¿Qué versiones de IE has probado, donde crees que causan problemas?
agregado el autor iconoclast, fuente
Parece que Crockford es por lo que no podemos tener cosas buenas. Eso y comentarios en JSON
agregado el autor Hejazzman, fuente
agregado el autor Tobu, fuente

Es posible que los programadores de PHP quieran consultar implode() . Esto toma una matriz se une con una cadena.

De los documentos ...

$array = array('lastname', 'email', 'phone');
echo implode(",", $array);//lastname,email,phone
11
agregado
Del mismo modo, JavaScript tiene join() . La mayoría de los idiomas tienen un método similar, o uno similar se puede codificar fácilmente.
agregado el autor Dan Burton, fuente
PHP tiene json_encode, que maneja todos los detalles de hacer JSON, no solo comas.
agregado el autor Brilliand, fuente
La mayoría de los idiomas, excepto Java.
agregado el autor Robert, fuente

As it's been already said, JSON spec (based on ECMAScript 3) doesn't allow trailing comma. ES >= 5 allows it, so you can actually use that notation in pure JS. It's been argued about, and some parsers did support it (http://bolinfest.com/essays/json.html, http://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/), but it's the spec fact (as shown on http://json.org/) that it shouldn't work in JSON. That thing said...

... Me pregunto por qué nadie señaló que en realidad se puede dividir el ciclo en la 0ª iteración y usar la coma inicial en lugar de seguir a uno para eliminar el olor del código de comparación y cualquier rendimiento real sobrecarga en el ciclo, lo que da como resultado un código que en realidad es más corto, más simple y más rápido (debido a que no hay bifurcaciones/condicionales en el ciclo) que otras soluciones propuestas.

P.ej. (en un pseudocódigo de estilo C similar al código propuesto por OP):

s.append("[");
// MAX == 5 here. if it's constant, you can inline it below and get rid of the comparison
if ( MAX > 0 ) {
    s.appendF("\"%d\"", 0);//0-th iteration
    for( int i = 1; i < MAX; ++i ) {
        s.appendF(",\"%d\"", i);//i-th iteration
    }
}
s.append("]");
8
agregado

Interestingly, both C & C++ (and I think C#, but I'm not sure) specifically allow the trailing comma -- for exactly the reason given: It make programmaticly generating lists much easier. Not sure why JavaScript didn't follow their lead.

6
agregado
PHP también lo permite. Creo que es la única característica de PHP que me gusta. ;pag
agregado el autor iconoclast, fuente
Las comillas finales funcionan en Firefox, pero no en IE.
agregado el autor kzh, fuente
ECMA ha especificado explícitamente que las comillas finales están permitidas en la próxima especificación: ejohn.org/blog/bug-fixes-in-javascript-2 Sin embargo, otra razón para dejar claro que JSON! = JS Object.
agregado el autor eyelidlessness, fuente

Use JSON5. No use JSON.

  • Los objetos y matrices pueden tener comas finales
  • Las claves de objeto se pueden desmarcar si son identificadores válidos
  • Las cadenas pueden ser citadas por una sola cotización
  • Las cadenas se pueden dividir en varias líneas
  • Los números pueden ser hexadecimales (base 16)
  • Los números pueden comenzar o terminar con un punto decimal (inicial o final).
  • Los números pueden incluir Infinity e -Infinity.
  • Los números pueden comenzar con un signo más (+) explícito.
  • Se permiten comentarios en línea (una sola línea) y de bloque (varias líneas).

http://json5.org/

https://github.com/aseemk/json5

5
agregado
Además, las cuerdas mutliline son terribles. Sueño con multilíneas ES6.
agregado el autor Marco Sulla, fuente
Se ve bien, pero no agregar nuevos tipos de datos parece una oportunidad perdida ... por supuesto, el deseo de seguir siendo un subconjunto estricto de ECMAScript 5 fuerza eso, pero aún así ...
agregado el autor iconoclast, fuente
No, ese es un consejo HORRIBLE. De todas las bibliotecas JSON existentes, muy pocas admiten dicha extensión; y todo esto para "mejoras" muy cuestionables. NO provoque una mayor erosión de la interoperabilidad con nuevas extensiones falsas como esta.
agregado el autor StaxMan, fuente
Creo que gastar tu vida en arreglar comas es más horrible.
agregado el autor user619271, fuente

Guardo un recuento actual y lo comparo con un recuento total. Si el recuento actual es menor que el recuento total, mostraré la coma.

Puede no funcionar si no tiene un recuento total antes de ejecutar la generación JSON.

Por otra parte, si usa PHP 5.2.0 o superior, puede formatear su respuesta utilizando la API JSON integrada.

1
agregado

De mi experiencia pasada, descubrí que diferentes navegadores tratan las comas finales en JSON de forma diferente.

Tanto Firefox como Chrome lo manejan bien. Pero IE (todas las versiones) parece romperse. Quiero decir realmente romper y dejar de leer el resto del guión.

Teniendo esto en cuenta, y también el hecho de que siempre es bueno escribir un código compatible, sugiero que se gaste un esfuerzo extra para asegurarse de que no haya una coma al final.

:)

1
agregado

De acuerdo con la especificación de Clase JSONArray :

  • Puede aparecer una coma adicional (coma) justo antes del corchete de cierre.
  • El valor nulo se insertará cuando haya, (coma) elisión.

Entonces, según lo entiendo, debería poder escribir:

[0,1,2,3,4,5,]

Pero podría suceder que algunos analizadores devuelvan el 7 como recuento de elementos (como IE8 como señaló Daniel Earwicker) en lugar de los 6 esperados.


Editado:

Encontré este Validador JSON que valida una cadena JSON contra RFC 4627 (Tipo de aplicación/json para la notación de objetos JavaScript) y en contra de la especificación del lenguaje JavaScript. De hecho, aquí una matriz con una coma final se considera válida solo para JavaScript y no para la especificación RFC 4627.

Sin embargo, en la especificación RFC 4627 se establece que:

2.3. Arrays

     

Una estructura de matriz se representa como corchetes que rodean cero   o más valores (o elementos). Los elementos están separados por comas.

 array = begin-array [value * (value-separator value]] end-array
 

Para mí, esto es nuevamente un problema de interpretación. Si escribe que Los elementos están separados por comas (sin indicar algo sobre casos especiales, como el último elemento), podría entenderse de ambas maneras.

P.S. RFC 4627 isn't a standard (as explicitly stated), and is already obsolited by RFC 7159 (which is a proposed standard) RFC 7159

1
agregado
La regla de gramática dada es tan precisa como puedes obtener. No hay forma de tener un value-separator sin un value justo al lado. También el texto es muy específico. La "separación de valores" solo se puede aplicar si hay múltiples valores. Entonces, si tiene dos valores uno al lado del otro, se separan usando una coma. Si tiene un valor (o si solo mira el valor al final), no hay separación, por lo tanto, no hay coma.
agregado el autor Steffen Heil, fuente

Normalmente recorro el conjunto y ato una coma después de cada entrada en la cadena. Después del ciclo, borro la última coma nuevamente.

Tal vez no sea la mejor manera, pero es menos costoso que comprobar siempre si es el último objeto del ciclo, supongo.

0
agregado

Con Relaxed JSON, puede tener comas al final, o simplemente dejar las comas . Ellos son opcionales

No hay ninguna razón para que las comas tengan que estar presentes para analizar un documento similar a JSON.

Eche un vistazo a la especificación Relaxed JSON y verá qué tan ruidosa es la especificación JSON original. Demasiadas comas y citas ...

http://www.relaxedjson.org

También puede probar su ejemplo utilizando este analizador RJSON en línea y ver cómo se analiza correctamente.

http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D

0
agregado

No es recomendable, pero aún puedes hacer algo como esto para analizarlo.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)
</div> </div>
0
agregado
JavaScript - Comunidad española
JavaScript - Comunidad española
4 de los participantes

En este grupo hablamos de JavaScript. Partner: es.switch-case.com