Are trailing commas in arrays and objects part of the spec?
Specs: ECMAScript 5 and ECMAScript 3
Section 11.1.5 in the ECMAScript 5 specification:
ObjectLiteral :
{ }
{ PropertyNameAndValueList }
{ PropertyNameAndValueList , }
So yes, it is part of the specification.
Update: Apparently this is new in ES5. In ES3 (page 41), the definition was just:
ObjectLiteral :
{ }
{ PropertyNameAndValueList }
For arrays literals (Section 11.1.4) it is even more interesting (Update: this already existed in ES3):
ArrayLiteral :
[ Elisionopt ]
[ ElementList ]
[ ElementList , Elision_opt ]
(where Elision_opt
is Elisionopt, meaning the Elision is optional)
Elision
is defined as
Elision :
,
Elision ,
So, an array literal like
var arr = [1,2,,,,];
is perfectly legal. This creates an array with two elements but sets the array length to 2 + 3 = 5
.
Don't expect too much from IE (before IE9)...
Can you use a trailing comma in a JSON object?
Unfortunately the JSON specification does not allow a trailing comma. There are a few browsers that will allow it, but generally you need to worry about all browsers.
In general I try turn the problem around, and add the comma before the actual value, so you end up with code that looks like this:
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("]");
That extra one line of code in your for loop is hardly expensive...
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 ;->).
Doesn't work well with an array unfortunately.
Will trailing commas break JSON?
You won't run into any problems, because JSON and JS source have nothing to do with each other.
JSON does not (and for the sake of example, will not) support trailing commas. The current JSON spec clearly shows that commas may only occur between values within an object or array.
If JS does introduce support for trailing commas, the source representation of the object and the version that is serialized are largely unrelated. Most browsers today will accept a trailing comma, but all commas are discarded in the actual object (dict/hash or struct) representation:
> var foo = {bar: 1, baz: 2,};
< undefined
> foo
< Object {bar: 1, baz: 2}
Even today, serializing an object with a trailing comma works just fine:
> JSON.stringify({bar: 1, baz: 2,})
< "{"bar":1,"baz":2}"
The commas are for parsing source only and do not exist in the runtime's object representation.
Why doesn't JSON tolerate trailing commas after the last element?
An array structure is represented as square brackets surrounding
zero or more values (or elements). Elements are separated by
commas.array = begin-array [ value *( value-separator value ) ] end-array
There is no requirement that the values in an array be of the same
type.
RFC 7159 section 5
Effectivly, trailing commas are not allowed as defined by the specification.
There are linting tools which will automagically fix it for you, but it's usually a sign you've done something wrong.
Why are trailing commas allowed in a list?
The main advantages are that it makes multi-line lists easier to edit and that it reduces clutter in diffs.
Changing:
s = ['manny',
'mo',
'jack',
]
to:
s = ['manny',
'mo',
'jack',
'roger',
]
involves only a one-line change in the diff:
s = ['manny',
'mo',
'jack',
+ 'roger',
]
This beats the more confusing multi-line diff when the trailing comma was omitted:
s = ['manny',
'mo',
- 'jack'
+ 'jack',
+ 'roger'
]
The latter diff makes it harder to see that only one line was added and that the other line didn't change content.
It also reduces the risk of doing this:
s = ['manny',
'mo',
'jack'
'roger' # Added this line, but forgot to add a comma on the previous line
]
and triggering implicit string literal concatenation, producing s = ['manny', 'mo', 'jackroger']
instead of the intended result.
Get Trailing commas( in JavaScript ) working in IE7/IE8
IE7/IE8 will report 1 element bigger array length, unless you trim those arrays.
If you know all JS methods which accepts data from 3rd party you can write wrapper for them. For example:
var removeEmpty = function(array){
var i, result = [];
for (i = 0; i < array.length; ++i){
if ( typeof array[i] != 'undefined' ){
result.push(array[i]);
}
}
return result;
};
$.supersized = (function() {
var origMethod = $.supersized;
return function(config) {
config.slides = removeEmpty(config.slides); // get rid of undefined data in array
return origMethod.call(this, config); // call original method
};
}());
Why leave a trailing comma after a key value pair in an object literal?
I tried this notation in Chrome and it is valid.
Simply because it works in Chrome doesn't mean it's valid. It is valid because the spec says so :-)
I wouldn't use this notation but why would people use it?
To make copy&pasting easier. You can just append new properties without caring additional work. It's a bad practice in program code because older browsers (notably IE) and the ES3 spec disallow them, but in a config file (i.e. in a known environment) it makes life easier.
Trailing comma in JavaScript function call
My team just ran into this issue with a user who has Chrome 55.0.2883.87.
This version of Chrome also reports unexpected token at ')' as reported above.
The trailing commas DO seem to be TOLERATED by Chrome 60.0.3112.113.
No error.
So we can deduce that Google is moving towards support for the trailing comma.
Array w/ all elements (except the first) undefined returns wrong length
This is a feature of array literals introduced back in ES3.
You can put leading or trilling commas as "empty" elements
so [,,,,1,2,3,,]
would yield an array of length 7, with first 4 and the last elements empty.
If you put this expression into the console in Firefox 34.0.5 it would say
Array [ <4 empty slots>, 1, 2, 3, <1 empty slot> ]
Sources:
Are trailing commas in arrays and objects part of the spec?
http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf
section 11.1.4
Related Topics
Two Sets of Parentheses After Function Call
Please Explain the Use of JavaScript Closures in Loops
Trying to Fire the Onload Event on Script Tag
Dealing with Float Precision in JavaScript
Are JavaScript Arrays Primitives? Strings? Objects
How to Get Node Datum on Mouseover in D3 V6
JavaScript Unit Test Tools for Tdd
How to Gain Access to the Closure of a Function
How to Add a Custom Right-Click Menu to a Webpage
Object Spread VS. Object.Assign
Differencebetween Children and Childnodes in JavaScript
Prevent Scrolling of Parent Element When Inner Element Scroll Position Reaches Top/Bottom
Js Client-Side Exif Orientation: Rotate and Mirror Jpeg Images
Make Axios Send Cookies in Its Requests Automatically
Get the Closest Number Out of an Array
How to Get Progress from Xmlhttprequest
Youtube Iframe API: How to Control an Iframe Player That's Already in the HTML
Is the Underscore Prefix for Property and Method Names Merely a Convention