分组运算符 ( )

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

试试看

语法

js
(expression)

参数

表达式

要评估的任何 表达式,包括 逗号连接 的表达式。

描述

分组运算符由一对括号组成,括号内包含一个表达式,该表达式对内容进行分组。该运算符会覆盖正常的 运算符优先级,因此具有较低优先级的运算符(低至 逗号 运算符)可以在具有较高优先级的运算符之前求值。

示例

使用分组运算符

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

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() 按从左到右的顺序(正常的求值顺序)在考虑运算符顺序之前求值。

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

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

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

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

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

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

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

您也可以使用 void 运算符来消除歧义。

箭头函数 表达式体中(直接返回表达式,没有关键字 return),可以使用分组运算符返回对象文字表达式,因为否则左花括号将被解释为函数体的开头。

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

如果在数字字面量上访问属性,属性访问器. 可能与小数点混淆,除非数字已经带一个小数点。您可以将整数字面量括在括号中以消除这种歧义。

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

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

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

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

此代码将返回 undefined,因为分号直接插入到 return 关键字之后,这会导致函数立即返回,而不会评估 a + b。如果返回的表达式很长,并且您想保持其格式良好,可以使用分组运算符来表示 return 关键字后跟一个表达式,并防止分号插入

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

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

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

此代码将被解析为

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

这将抛出 "TypeError: 1 is not a function"。如果您的编码风格不使用分号,请记住,当一行以左括号开头时,请在前面加上分号。这种做法是许多格式化程序和/或风格指南(包括 Prettierstandard)推荐的。

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

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

规范

规范
ECMAScript 语言规范
# sec-grouping-operator

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅