A trailing comma, also known as a dangling or terminal comma, is a comma symbol that is typed after the last item of a list of elements. Since the introduction of the JavaScript language, trailing commas have been legal in array literals. Later, object literals joined arrays. And with the introduction of ES2017, also known as ES8, trailing commas became allowed pretty much everywhere.
It seems like a little change, but there are some hard-to-notice consequences. And while most new language features are welcomed, this one can land you in trouble if you’re not careful.
In this guide, we’ll look at trailing commas in detail. We’ll start with the common data types, like arrays and objects, where you can safely add a trailing comma to the end of a list of items. Then we’ll move on to language constructs such as parameter lists, function calls, and destructuring assignments. At the end of the article, we’ll discuss the dos and don’ts of using trailing commas.
You can safely include a trailing comma after the last expression in an array like this:
const arr = [ "one", "two", "three", ];
Be careful not to add more than one comma to the end, or you’ll be creating an undefined
element. For example, the following array is perfectly legal but contains four elements:
const arr = [ "one", "two", "three",, ]; console.log(arr.length); // => 4
Arrays don’t necessarily have contiguous indices starting at 0
. You can create an array that contains several “gaps” — such an array is known as a sparse array. For instance, the following array contains six elements, three of which are undefined
:
const sparseArray = [1,,,4,5,,];
So, it’s important to remember that the value of the length
property doesn’t always indicate the number of elements in the array. You may even have an array that has no elements and a length of 1
:
const arr = [,]; console.log(arr.length); // => 1
In practice, however, you rarely need to work with a sparse array. And if you do, your existing code will most likely handle it just as it would handle a normal array containing undefined
elements.
Similar to arrays, you can have a comma following the last property of an object:
const person = { firstName: "John", lastName: "Davis", age: 30, }
Trailing commas in object literals have been legal since ECMAScript 5. Some JavaScript style guides, like those created by Airbnb and Google, even encourage you to make a habit of including a trailing comma all the time so that you’re less likely to encounter a syntax error when adding a new property at the end of an object at a later time.
Note that, unlike with arrays, you cannot create sparse objects, and attempting to do so results in a syntax error:
const person = { firstName: "John", , age: 30, } // logs: // => Uncaught SyntaxError: Unexpected token ','
As I mentioned before, there are several other constructs in JavaScript besides arrays and objects that may have a trailing comma.
It’s sometimes useful to put the parameters of a function on a separate line, particularly if there’s a long list of parameters or you want to accommodate comments describing each parameter. For example:
function createRectangle( w, // (number) the width of the rectangle h // (number) the height of the rectangle ) { /* ... */ }
As the function evolves, you may find yourself in a situation where you need to add more parameters to the function. But for each new parameter you add, you have to go to the previous line and add a comma:
function createRectangularPrism( w, // (number) the width h, // (number) the height d // (number) the depth ) { /* ... */ }
Even experienced developers do not always remember to add a comma to the previous line, which results in an error. What’s worse is that the commit diffs will show a code change in that line simply because you later added a comma (more on this later).
Fortunately, ES2017 made it legal to add a trailing comma to function parameters, too:
function createRectangularPrism( w, // (number) the width h, // (number) the height d, // (number) the depth ) { /* ... */ }
This is just a change in the coding style and doesn’t add an unnamed parameter or cause any other side effect.
What’s more, the ES2017 update gave us the ability to have a trailing comma at the ends of arguments in function calls. Some programmers like to put each argument of a function call on its own line. If you’re one of them, then trailing commas, again, will save you from potential errors in the future:
createRectangle ( 5, 10, )
This code calls the createRectangle()
function with two arguments. If you later decide to add a third argument, you won’t have to edit any existing line. The same rule applies to method definitions for classes or objects since they’re also functions:
const myObj = { createRectangle( // defines a method w, h, ) { /* ... */ } }
The destructuring assignment syntax allows you to quickly extract values from arrays or objects into distinct variables. When destructuring, you can add a trailing comma to the left-hand side of the assignment. For instance, the following code destructures an array:
const numbers = [10, 20, 30]; const [n1, n2, n3,] = numbers; console.log(n1); // => 10
Similarly, you can use destructuring to “unpack” the properties of an object:
const car = { color: 'red', type: 'coupe', hp: 500 }; const {color, type, hp,} = car; console.log(color); // => red
But what about JSON objects, which are similar to plain JavaScript objects? Can they use trailing commas?
The JSON file format was introduced in the early 2000s. Since JSON is based on JavaScript’s object syntax, and it was invented before ECMAScript 5 was introduced in 2009, trailing commas cannot be used in JSON (remember, trailing commas in object literals became legal in ES5).
For example, the following code will throw an error:
JSON.parse('[1, 2, 3, 4, ]'); // => Uncaught SyntaxError: Unexpected token ] in JSON at position 13
So does this line of code:
JSON.parse('{"foo" : 1, }'); // => Uncaught SyntaxError: Unexpected token } in JSON at position 12
There are a number of online tools that can help you with this problem. For example, you can take advantage of this JSON Formatter to automatically find and remove trailing commas in your JSON code.
In modern JavaScript, it’s a common practice to create programs that are composed of independent chunks of code called modules. Just as it’s legal to add a trailing comma to objects in classic scripts, it’s legal to have a comma following the last item of exports in modules. This comes in handy when you want to include more exports at a later time. For example:
// module 1 var foo = 10; let bar = 20; const baz = 30; export {foo, bar, baz, };
This code uses the export
keyword to make the foo
, bar
, and baz
variables public. This means other modules in separate files can use the import
statement to access these variables:
// module 2 import { foo, bar, baz, // notice the trailing comma, which is legal when importing identifiers } from './module1.js'
JavaScript programmers used to avoid including a trailing comma in arrays because early versions of Internet Explorer would throw an error (even though it was legal in JavaScript from the beginning). But things have changed. Many coding styles now recommend using trailing commas all the time, and there are good reasons for that.
If you frequently add new items to the ends of arrays, objects, or argument/parameter lists, then having a trailing comma already in place means you won’t have to remember to go to the line before and add a comma if you need to make an addition later.
You may also find yourself frequently cutting and pasting properties. Again, having a trailing comma could make reordering the items less troublesome and prevent syntax errors in the future.
Moreover, because you won’t need to change the line that used to be the last item, version control systems would produce cleaner diffs. Say you have this function:
function myFunction( p1, p2 ) { /* ... */ } myFunction( 'arg1', 'arg2' );
If you add a new parameter called p3
, the diff output would look something like:
function myFunction( p1, - p2 + p2, // Change this line to add a comma + p3 // Add p3 ) { /* ... */ } myFunction ( 'arg1', - 'arg2' + 'arg2', // Change this line to add a comma + 'arg3' // Add arg3 );
Here, you have two changes in the function declaration and two changes in the function invocation. Let’s see what would happen if your function already had a trailing comma:
function myFunction( p1, p2, ) { /* ... */ } myFunction( 'arg1', 'arg2', );
With a trailing comma in place, you’ll only have two changes in the diff output:
function myFunction( p1, p2, + p3 // Add p3 ) { /* ... */ } myFunction ( 'arg1', 'arg2', + 'arg3' // Add arg3 );
The takeaway from this section is that using trailing commas makes it easier to add new parameters to your functions or copy/paste properties in arrays and objects. It also helps with producing cleaner diff output.
But trailing commas do not work everywhere, and if you’re not careful, using them might actually backfire.
You might assume that you can use trailing commas with the rest parameter syntax, too, because trailing commas are allowed in various other JavaScript constructs. But that is actually not true:
function sum(...theArgs,) { // notice the trailing comma return theArgs.reduce((previous, current) => { return previous + current; }); } console.log(sum(1, 2, 3)); // => Uncaught SyntaxError: parameter after rest parameter
Using a trailing comma after the rest parameter is illegal, even if you use it in the destructuring syntax:
const numbers = [10, 20, 30]; const [n1, ...n2,] = numbers; // => Uncaught SyntaxError: rest element may not have a trailing comma
So, keep in mind that although using a trailing comma in destructuring syntax is valid, you cannot use it after the rest parameter.
Besides the destructuring syntax, there’s one more place where using a trailing comma may land you in trouble: functions. Consider the following example:
function myFunction(,) { // ... } // => Uncaught SyntaxError: Unexpected token ',' myFunction(,); // => Uncaught SyntaxError: Unexpected token ','
The first line of this code defines a function with no parameter and a comma, and that causes a SyntaxError
. You can either have no parameters with no comma, or a trailing comma after parameters. The same is true when you invoke a function: you cannot have a function call whose only argument is a comma.
The usage of the comma symbol has undergone several revisions in the JavaScript language, and with each revision, more language constructs have added support for trailing commas. In this article, we looked at how the trailing comma works in different constructs, including arrays, objects, JSON objects, parameter lists, function calls, and module imports and exports.
Then, we learned where the trailing comma is legal to use and where it’s not. In general, you should make use of trailing commas when you frequently copy/paste properties or add new items to the end of a list. You can also take advantage of them to produce cleaner diff outputs. But, remember, you should not use them with the rest parameter syntax, and you cannot have a function declaration/invocation whose only parameter is a comma.
Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.
LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.
LogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
2 Replies to "Best practices for using trailing commas in JavaScript"
👍🏽 nice summary. Thanks 🙏🏽.
Very bikeshed. The only meaningful arguments I’ve ever heard in support of the practice are “it makes templating and transformation by regex easier.” The compiler certainly doesn’t care in operational cases.
“Cleaner” diffs are an opinion on the order of “clean code,” albeit with marginally superior provenance. If you’ve seen a few diffs, you know what you’re looking at from experience. If you haven’t, the reduction is fairly obvious.
There’s a stronger argument to be made here for left-sided dots and commas. All the benefits if you care, no fashion characters.