Faraz Kelhini JavaScript developer.

Best practices for using trailing commas in JavaScript

6 min read 1872

Best practices for trailing commas in JavaScript

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.

Using trailing commas in arrays

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.

Using trailing commas in objects

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.

We made a custom demo for .
No really. Click here to check it out.

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.

Using trailing commas in parameter lists and function calls

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,
  ) { /* ... */ }
}

Using trailing commas in the destructuring assignment syntax

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?

Using trailing commas in JSON

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.

Trailing commas in module imports and exports

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'

Why should you start using trailing commas?

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.

When not to use trailing commas

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.

Conclusion

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.

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

: Debug JavaScript errors easier by understanding the context

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 find out exactly what the user did that led to an error.

LogRocket records console logs, page load times, stacktraces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

.
.
Faraz Kelhini JavaScript developer.

Testing accessibility with Storybook

One big challenge when building a component library is prioritizing accessibility. Accessibility is usually seen as one of those “nice-to-have” features, and unfortunately, we’re...
Laura Carballo
4 min read

One Reply to “Best practices for using trailing commas in JavaScript”

Leave a Reply