¿Las comas finales en matrices y objetos son parte de la especificación?

215

¿Las comas finales son estándar en JavaScript, o la mayoría de los navegadores como Chrome y Firefox simplemente las toleran?

Pensé que eran estándar, pero IE8 vomitó después de encontrar uno; por supuesto, IE no admite algo difícilmente significa que no es estándar.

Aquí hay un ejemplo de lo que quiero decir (después del último elemento de la matriz de libros):

var viewModel = {
    books: ko.observableArray([
        { title: "..", display: function() { return ".."; } },
        { title: "..", display: function() { return ".."; } },
        { title: "..", display: function() { return ".."; } }, // <--right there
    ]),
    currentTemplate: ko.observable("bookTemplate1"),
    displayTemplate: function() { return viewModel.currentTemplate(); }
};
Adam Rackis
fuente
Encontré esto el otro día. Siendo un programador de C #, estaba tan acostumbrado a que se les permitiera ...
CaffGeek
55
Me ocupé de esto hace unas semanas. Imagínese tratando de encontrar esto en IE7 sin ninguna de las nuevas herramientas de depuración ...
Ryan Miller
44
Me hizo feliz cuando descubrí que lenguajes como JS, Ruby, C # admiten esto, hace que copiar datos de prueba de pegado sea fácil ... me enojó cuando me di cuenta de que IE apesta incluso en esto ...
Adam Rackis
Me pregunto si un espacio en blanco significativo en lugar de comas (como CoffeeScript) causaría alguna ambigüedad sintáctica.
Andy

Respuestas:

209

Especificaciones: ECMAScript 5 y ECMAScript 3


Sección 11.1.5 en la especificación ECMAScript 5:

ObjectLiteral :
    { }
    { PropertyNameAndValueList }
    { PropertyNameAndValueList , }

Entonces sí, es parte de la especificación.

Actualización: aparentemente esto es nuevo en ES5. En ES3 (página 41), la definición era solo:

ObjectLiteral :
    { }
    { PropertyNameAndValueList }

Para los literales de matrices ( Sección 11.1.4 ) es aún más interesante ( Actualización: esto ya existía en ES3):

ArrayLiteral :
    [ Elisionopt ]
    [ ElementList ]
    [ ElementList , Elision_opt ]

(donde Elision_optestá optado Elision , lo que significa que Elision es opcional)

Elision Se define como

Elision :
    ,
    Elision ,

Entonces, una matriz literal como

var arr = [1,2,,,,];

Es perfectamente legal. Esto crea una matriz con dos elementos pero establece la longitud de la matriz en 2 + 3 = 5.

No esperes demasiado de IE (antes de IE9) ...

Felix Kling
fuente
1
Como le pregunté a EndoPhage, ¿sabe si esto también era estándar en ES3? Parece que no puedo encontrar la especificación para ello
Adam Rackis
1
Aparentemente, la coma final en literales de objeto no estaba en la especificación ES3. Pero la definición de matrices es la misma.
Felix Kling
Bueno, fue con elementos de matriz con los que me topé, así que supongo que no hay excusa para la EM, sin importar cómo la corte. Gracias de nuevo
Adam Rackis
Vergüenza en Micro $ oft Internet Explorer
pylover
91

Solo un recordatorio / advertencia rápida de que esta es una de las áreas en las que difieren el estándar JavaScript / ECMAScript y el estándar JSON ; las comas finales son válidas en JS pero no válidas en JSON.

Joey Sabey
fuente
1
Pero, de nuevo, si el superconjunto se encuentra en un "Cambio de corazón", "¿Podría (todavía) ser amado" si solo se ajustara por una vez?
Lukas Bünger el
52

Lo que es aún más divertido, IE7 da

[1,].length  --> 2

mientras que Firefox y Chrome

[1,].length  --> 1
Seeg
fuente
16
Pero [1,,].lengthda 2. Sentido : los navegadores no hacen ninguno.
David Titarenco
84
Tiene mucho sentido, la especificación dice que una coma final (nota: singular) no se suma a la longitud de una matriz. Chrome y Firefox han implementado ES5 correctamente.
JaredMcAteer
77
Cuando hay 2 comas finales (en plural), solo una se suma a la longitud de la matriz, por lo que parece más exacto decir que la coma final se ignora que decir que se ignora una coma final.
iconoclasta
4

Puede encontrar la especificación para javascript (también conocido como ECMA Script) aquí . Puede encontrar la definición relevante para las matrices en la página 63 y, como señaló Felix, la definición del objeto un par de páginas más adelante en la página 65.

Si bien esta especificación dice que está bien tener un seguimiento ,, no sé si eso sería cierto mirando hacia atrás algunas versiones. Como ha notado, IE8 se arruinará si deja una coma final, pero Chrome y FF lo manejan bien.

Endophage
fuente
Fuera de la cabeza, ¿era parte del estándar ES3? Parece que no puedo encontrar la especificación ES3
Adam Rackis
1
@ Adam, he estado tratando de encontrarlo ... Dadas las fechas de lanzamiento (ES3 se publicó en 1999, ES4 se abandonó y ES5 solo se publicó en 2009), tendría sentido que estuviera en el estándar ES3. O podría ser simplemente que MS arruinó una cosa más.
Endophage
Parece que MS arruinó una cosa más dada la respuesta de Felix. Gracias de nuevo por la suya
Adam Rackis
2

Analicemos esto.

¿Las comas finales son estándar en JavaScript?

Si. A partir de la especificación ECMAScript 5 (también parte de la guía de estilo de Google y Airbnb)

¿La mayoría de los navegadores como Chrome y Firefox simplemente los toleran?

Esta es una pregunta de soporte de ECMAScript 5.

Los transpiladores como Babel eliminarán la coma adicional adicional en el código transpilado, lo que significa que no tiene que preocuparse por el problema de la coma final en los navegadores heredados.

Entonces eso significa:

var heroes = [
  'Batman',
  'Superman',
];
// heroes.length === 2 (not 3)

Por lo tanto, es probable que si está usando algo ES5 y superior, no necesita preocuparse por eso.

Pensé que eran estándar, pero IE8 vomitó después de encontrar uno; por supuesto, IE no admite algo difícilmente significa que no es estándar.

Nuevamente, esa es una pregunta de soporte de ECMAScript 5. IE8 no es compatible con ECMAScript 5 (solo IE9 y superior)

Recomiendo echar un vistazo a la documentación obsoleta ES5 de Airbnb https://github.com/airbnb/javascript/blob/es5-deprecated/es5/README.md#commas

También recomendaría los documentos de Mozilla:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas

garrettmac
fuente
1

En Chrome 52:

[1,].length --> 1
[1,2,].length --> 2
[].length --> 0 
[,].length --> 1    <<<<=== OUHHHHH !!!!

Simplemente no me gustan las comas finales. La gente generalmente los usa en proyectos de código abierto para evitar borrar la línea escrita por otro comisionado. Vea la misma pregunta en Python: https://stackoverflow.com/a/11597911/968988

Nicolas Zozol
fuente
13
¿Por qué 'OUHHHHH'? ¿Qué más esperabas allí si no 1? Claramente 'tienes un elemento' antes de esa coma, al igual que [1,] (que es la longitud: 1).
Fygo
¿Por qué 'OUHHHHH'? porque no espero nada de un código que no entiendo sin leer el RFC. Y sí, funciona igual que [1,]: claramente hay algo antes de la coma. Pero [,]hay tanto antes como después de la coma. Entonces, como no entiendo [,]solo, no creo que usar [1,]sea ​​una buena idea.
Nicolas Zozol