尾后逗号 （有时叫做“终止逗号”）在向 JavaScript 代码添加元素、参数、属性时十分有用。如果你想要添加新的属性，并且上一行已经使用了尾后逗号，你可以仅仅添加新的一行，而不需要修改上一行。这使得版本控制的比较更加清晰，以及代码便器的麻烦更少。

JavaScript 一开始就支持数组字面值中的尾后逗号，随后向对象字面值（ECMAScript 5）中添加了尾后逗号。最近（ECMAScript 2017），又将其添加到函数参数中。

但是 JSON 不支持尾后逗号。

## 字面值中的尾后逗号

### 数组

JavaScript 忽略数组中的尾后逗号：

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

    arr; // [1, 2, 3]
    arr.length; // 3

如果使用了多于一个尾后逗号，会产生省略（或者间隙）。 带有间隙的数组叫做稀疏数组（密致数组没有间隙）。 例如，当使用 `Array.prototype.forEach()` 或 `Array.prototype.map()` 迭代数组时，会跳过数组间隙。

    var arr = [1, 2, 3,,,];
    arr.length; // 5

### 对象

从 ECMAScript 5 开始，对象字面值中的尾后逗号也是合法的：

    var object = {
      foo: "bar",
      baz: "qwerty",
      age: 42,
    };

## 函数中的尾后逗号

ECMAScript 2017 支持函数参数中的尾后逗号。

### 参数定义

下面的两个函数定义都是合法的，并且互相等价。尾后逗号并不影响函数定义，或者其`arguments`对象的 `length`属性。

    function f(p) {}
    function f(p,) {}

    (p) => {};
    (p,) => {};

尾后逗号也可用于类或对象的方法定义。

    class C {
      one(a,) {},
      two(a, b,) {},
    }

    var obj = {
      one(a,) {},
      two(a, b,) {},
    };

### 函数调用

下面的两个函数调用都是合法的，并且互相等价。

    f(p);
    f(p,);

    Math.max(10, 20);
    Math.max(10, 20,);

### 不合法的尾后逗号

仅仅包含逗号的函数参数定义或者函数调用会抛出 `SyntaxError`。 而且，当使用剩余参数的时候，并不支持尾后逗号：

    function f(,) {} // SyntaxError: missing formal parameter
    (,) => {};       // SyntaxError: expected expression, got ','
    f(,)             // SyntaxError: expected expression, got ','

    function f(...p,) {} // SyntaxError: parameter after rest parameter
    (...p,) => {}        // SyntaxError: expected closing parenthesis, got ','

## 解构中的尾后逗号

在使用解构赋值时，尾后逗号也可以用于左侧：

    // 带有尾后逗号的数组解构
    [a, b,] = [1, 2];

    // 带有尾后逗号的对象解构
    var o = {
      p: 42,
      q: true,
    };
    var {p, q,} = o;

同样，使用剩余参数时，出抛出 `SyntaxError`：

    var [a, ...b,] = [1, 2, 3];
    // SyntaxError: rest element may not have a trailing comma

## JSON 中的尾后逗号

对象中的尾后逗号仅仅在 ECMAScript 5 中引入。由于 JSON 基于 ES5 之前的语法， JSON 中并不支持尾后逗号。

下面两行都会抛出 `SyntaxError`：

    JSON.parse('[1, 2, 3, 4, ]');
    JSON.parse('{"foo" : 1, }');
    // SyntaxError JSON.parse: unexpected character
    // at line 1 column 14 of the JSON data

去掉尾后逗号，使 JSON 正确解析：

    JSON.parse('[1, 2, 3, 4 ]');
    JSON.parse('{"foo" : 1 }');

## 规范

Specification | Status | Comment
--- | --- | ---
ECMAScript 5.1 (ECMA-262) | Standard | Added object literal trailing commas.
ECMAScript 2015 (6th Edition, ECMA-262) | Standard | No change.
ECMAScript Latest Draft (ECMA-262) | Draft | ES2017 added trailing function commas.

## 浏览器兼容

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

| Desktop | Mobile | Server
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js
Trailing commas | Chrome Full support Yes | Edge Full support Yes | Firefox Full support 1 | IE Full support Yes | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes
Trailing comma in object literals | Chrome Full support Yes | Edge Full support Yes | Firefox Full support 1 | IE Full support 9 | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes
Trailing comma in functions | Chrome Full support 58 | Edge No support No | Firefox Full support 52 | IE No support No | Opera No support No | Safari No support No | WebView Android No support No | Chrome Android Full support 58 | Edge Mobile No support No | Firefox Android Full support 52 | Opera Android No support No | Safari iOS No support No | Samsung Internet Android Full support 7.0 | nodejs Full support 8.0.0

### Legend

Full support
  Full support
No support
  No support

## 参见

- ECMAScript 初始提案： 函数的尾后逗号（由 Jeff Morrison 提出）