分组运算符 ( )

分组 ( ) 运算符控制表达式中求值的优先级。它还充当某些语法结构中任意表达式的容器,否则会出现歧义或语法错误。

¥The grouping ( ) operator controls the precedence of evaluation in expressions. It also acts as a container for arbitrary expressions in certain syntactic constructs, where ambiguity or syntax errors would otherwise occur.

Try it

语法

¥Syntax

js
(expression)

参数

¥Parameters

expression

任何要计算的 expression,包括 comma-joined 表达式。

描述

¥Description

分组运算符由对内容进行分组的表达式两边的一对括号组成。该运算符会覆盖正常的 运算符优先级,因此优先级较低的运算符(低至 comma 运算符)可以在优先级较高的运算符之前进行计算。

¥The grouping operator consists of a pair of parentheses around an expression that groups the contents. The operator overrides the normal operator precedence, so that operators with lower precedence (as low as the comma operator) can be evaluated before an operator with higher precedence.

示例

¥Examples

使用分组运算符

¥Using the grouping operator

在乘法和除法之前评估加法和减法。

¥Evaluating addition and subtraction before multiplication and division.

js
const a = 1;
const b = 2;
const c = 3;

// default precedence
a + b * c; // 7
// evaluated by default like this
a + (b * c); // 7

// now overriding precedence
// addition before multiplication
(a + b) * c; // 9

// which is equivalent to
a * c + b * c; // 9

请注意,在这些示例中,运算符求值的顺序已更改,但操作数求值的顺序未更改。例如,在此代码中,在考虑运算符顺序之前,从左到右(正常的求值顺序)对函数调用 a()b()c() 求值。

¥Notice in these examples that the order in which the operators evaluate has changed, but the order in which the operands evaluate has not. For example, in this code, the function invocations a(), b(), and c() are evaluated left-to-right (the normal order of evaluation) before the operator order is considered.

js
a() * (b() + c());

函数 a 将在函数 b 之前调用,函数 b 将在函数 c 之前调用。有关运算符优先级的更多信息,请参阅其 参考页

¥The function a will be called before the function b, which will be called before the function c. For more on operator precedence, see its reference page.

使用分组运算符消除解析歧义

¥Using the grouping operator to eliminate parsing ambiguity

表达式语句 不能以关键字 function 开头,因为解析器会将其视为 函数声明 的开头。这意味着以下 IIFE 语法无效:

¥An expression statement cannot start with the keyword function, because the parser would see it as the start of a function declaration. This means the following IIFE syntax is invalid:

js
function () {
  // code
}();

分组运算符可用于消除这种歧义,因为当解析器看到左括号时,它知道后面的必须是表达式而不是声明。

¥The grouping operator can be used to eliminate this ambiguity, since when the parser sees the left parenthesis, it knows that what follows must be an expression instead of a declaration.

js
(function () {
  // code
})();

你还可以使用 void 运算符来消除歧义。

¥You may also use the void operator to eliminate ambiguity.

箭头函数 表达式体(直接返回不带关键字 return 的表达式)中,分组运算符可用于返回对象字面量表达式,否则左大括号将被解释为函数体的开头。

¥In an arrow function expression body (one that directly returns an expression without the keyword return), the grouping operator can be used to return an object literal expression, because otherwise the left curly brace would be interpreted as the start of the function body.

js
const f = () => ({ a: 1 });

如果通过数字文字访问属性,则 属性访问器. 与小数点可能不明确,除非该数字已经有小数点。你可以将整数文字括在括号中以消除这种歧义。

¥If a property is accessed on a number literal, the property accessor dot . may be ambiguous with a decimal point, unless the number already has a decimal point. You can wrap integer literals in parentheses to eliminate this ambiguity.

js
(1).toString(); // "1"

分组运算符和自动分号插入

¥Grouping operator and automatic semicolon insertion

分组运算符可以减轻 自动插入分号 (ASI) 陷阱。例如,return 关键字和返回的表达式之间不能有换行符:

¥The grouping operator can mitigate automatic semicolon insertion (ASI) pitfalls. For example, the return keyword and the returned expression cannot have a line break in between:

js
function sum(a, b) {
  return
    a + b;
}

此代码将返回 undefined,因为在 return 关键字后面直接插入了分号,这导致函数立即返回而不计算 a + b。如果返回的表达式很长并且你希望保持其格式正确,则可以使用分组运算符来表示 return 关键字后面跟着一个表达式并防止插入分号:

¥This code will return undefined, because a semicolon is inserted directly after the return keyword, which causes the function to return immediately without evaluating a + b. In case the returned expression is long and you want to keep it well-formatted, you may use the grouping operator to signify that the return keyword is followed by an expression and prevent semicolon insertion:

js
function sum(a, b) {
  return (
    a + b
  );
}

然而,分组也可能引入 ASI 危险。当一行以左括号开头并且前一行以表达式结束时,解析器不会在换行符之前插入分号,因为它可能是函数调用的中间。例如:

¥However, grouping may also introduce ASI hazards. When a line starts with a left parenthesis and the previous line ends with an expression, the parser will not insert a semicolon before the line break, because it could be the middle of a function call. For example:

js
const a = 1
(1).toString()

这段代码将被解析为:

¥This code would be parsed as:

js
const a = 1(1).toString();

这会抛出“类型错误:1 不是一个函数”。如果你的编码风格不使用分号,请记住,当一行以左括号开头时,请在其前面加上分号。多个格式化程序和/或样式指南(包括 Prettierstandard)推荐了这种做法。

¥Which throws "TypeError: 1 is not a function". If your coding style does not use semicolons, remember that when a line starts with a left parenthesis, prefix it with a semicolon. This practice is recommended by several formatters and/or style guides, including Prettier and standard.

js
const a = 1
;(1).toString()

有关使用 ASI 的更多建议,请参阅其 参考部分

¥For more advice on working with ASI, see its reference section.

规范

Specification
ECMAScript Language Specification
# sec-grouping-operator

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看