尾随逗号

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

* 此特性的某些部分可能存在不同级别的支持。

末尾逗号(有时也称为“最终逗号”)在向 JavaScript 代码添加新元素、参数或属性时非常有用。如果你想添加一个新属性,如果上一行已经使用了末尾逗号,你就可以添加新行而无需修改上一行。这使得版本控制的差异(diff)更清晰,并且编辑代码可能也更省事。

JavaScript 从一开始就允许在数组字面量中使用末尾逗号。现在,对象字面量、函数参数、命名导入、命名导出等也允许使用末尾逗号。

然而,JSON 不允许所有末尾逗号。

描述

JavaScript 允许在接受逗号分隔的值列表且最后一个项后可能还有更多值的地方使用末尾逗号。这包括:

在所有这些情况下,末尾逗号都是完全可选的,并且不会以任何方式改变程序的语义。

当添加、删除或重新排序跨越多行的列表中的项时,它特别有用,因为它减少了需要更改的行数,这有助于编辑和审查差异(diff)。

diff
  [
    "foo",
+   "baz",
    "bar",
-   "baz",
  ]

示例

字面量中的末尾逗号

数组

JavaScript 会忽略数组字面量中的末尾逗号

js
const arr = [
  1,
  2,
  3,
];

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

如果使用多个末尾逗号,则会产生一个省略(或空洞)。带有空洞的数组称为稀疏数组密集数组没有空洞)。当迭代数组时,例如使用Array.prototype.forEach()Array.prototype.map(),数组空洞会被跳过。稀疏数组通常不受欢迎,所以你应该避免使用多个末尾逗号。

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

对象

对象字面量中的末尾逗号也是合法的

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

函数中的末尾逗号

函数参数列表中也允许使用末尾逗号。

参数定义

以下函数定义对是合法的,并且彼此等价。末尾逗号不影响函数声明的length属性或它们的arguments对象。

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

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

末尾逗号也适用于类或对象的方法定义

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

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

函数调用

以下函数调用对是合法的,并且彼此等价。

js
f(p);
f(p,);

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

非法的末尾逗号

仅包含逗号的函数参数定义或函数调用将抛出SyntaxError。此外,当使用剩余参数时,不允许使用末尾逗号

js
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 ','

解构中的末尾逗号

解构模式中也允许使用末尾逗号

js
// array destructuring with trailing comma
[a, b,] = [1, 2];

// object destructuring with trailing comma
const o = {
  p: 42,
  q: true,
};
const { p, q, } = o;

然而,如果存在剩余元素,则不允许在剩余元素之后使用末尾逗号

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

JSON 中的末尾逗号

由于 JSON 基于 JavaScript 语法的非常受限的子集,JSON 中不允许使用末尾逗号

这两行都将抛出SyntaxError

js
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

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

命名导入和命名导出中的末尾逗号

命名导入命名导出中允许使用末尾逗号。

命名导入

js
import {
  A,
  B,
  C,
} from "D";

import { X, Y, Z, } from "W";

import { A as B, C as D, E as F, } from "Z";

命名导出

js
export {
  A,
  B,
  C,
};

export { A, B, C, };

export { A as B, C as D, E as F, };

动态导入中的末尾逗号

只有当运行时也实现了第二个options参数时,动态导入中才允许使用末尾逗号。

js
import("D",);
import(
  "D",
  { with: { type: "json" } },
);

量词前缀

注意:量词中的末尾逗号实际上会改变其语义,从匹配“恰好n个”变为匹配“至少n个”。

js
/x{2}/; // Exactly 2 occurrences of "x"; equivalent to /xx/
/x{2,}/; // At least 2 occurrences of "x"; equivalent to /xx+/
/x{2,4}/; // 2 to 4 occurrences of "x"; equivalent to /xxx?x?/

规范

规范
ECMAScript® 2026 语言规范
# prod-Elision
ECMAScript® 2026 语言规范
# prod-ObjectLiteral
ECMAScript® 2026 语言规范
# prod-ArrayLiteral
ECMAScript® 2026 语言规范
# prod-Arguments
ECMAScript® 2026 语言规范
# prod-FormalParameters
ECMAScript® 2026 语言规范
# prod-CoverParenthesizedExpressionAndArrowParameterList
ECMAScript® 2026 语言规范
# prod-NamedImports
ECMAScript® 2026 语言规范
# prod-NamedExports
ECMAScript® 2026 语言规范
# prod-QuantifierPrefix
ECMAScript® 2026 语言规范
# prod-annexB-InvalidBracedQuantifier

浏览器兼容性

另见