分组运算符 ( )
分组 ( )
运算符控制表达式中求值的优先级。它也充当特定语法结构中任意表达式的容器,否则会发生歧义或语法错误。
试一试
console.log(1 + 2 * 3); // 1 + 6
// Expected output: 7
console.log(1 + (2 * 3)); // 1 + 6
// Expected output: 7
console.log((1 + 2) * 3); // 3 * 3
// Expected output: 9
console.log(1 * 3 + 2 * 3); // 3 + 6
// Expected output: 9
语法
(expression)
参数
描述
分组运算符由一对括号括起来的表达式组成,用于对内容进行分组。该运算符会覆盖正常的运算符优先级,因此优先级较低的运算符(甚至低至逗号运算符)可以在优先级较高的运算符之前进行计算。
示例
使用分组运算符
在乘法和除法之前计算加法和减法。
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()
在考虑运算符顺序之前从左到右(正常的计算顺序)进行计算。
a() * (b() + c());
函数 a
将在函数 b
之前调用,函数 b
将在函数 c
之前调用。有关运算符优先级的更多信息,请参阅其参考页。
使用分组运算符消除解析歧义
表达式语句不能以关键字 function
开头,因为解析器会将其视为函数声明的开始。这意味着以下 IIFE 语法无效
function () {
// code
}();
分组运算符可以消除这种歧义,因为当解析器看到左括号时,它知道接下来必须是一个表达式而不是一个声明。
(function () {
// code
})();
你也可以使用 void
运算符来消除歧义。
在箭头函数表达式体中(直接返回表达式而没有关键字 return
的那种),分组运算符可以用于返回对象字面量表达式,因为否则左花括号将被解释为函数体的开始。
const f = () => ({ a: 1 });
如果数字字面量上访问属性,属性访问器点 .
可能会与小数点混淆,除非数字已经包含小数点。你可以用括号将整数字面量括起来以消除这种歧义。
(1).toString(); // "1"
分组运算符和自动分号插入
分组运算符可以缓解自动分号插入(ASI)的陷阱。例如,return
关键字和返回的表达式之间不能有换行符
function sum(a, b) {
return
a + b;
}
这段代码将返回 undefined
,因为在 return
关键字之后直接插入了一个分号,导致函数立即返回而没有计算 a + b
。如果返回的表达式很长并且你想保持其良好的格式,你可以使用分组运算符来表示 return
关键字后面跟着一个表达式,并防止分号插入
function sum(a, b) {
return (
a + b
);
}
然而,分组也可能引入 ASI 危害。当一行以左括号开头,并且前一行以表达式结尾时,解析器不会在换行符之前插入分号,因为它可能是函数调用的中间。例如
const a = 1
(1).toString()
这段代码将被解析为
const a = 1(1).toString();
这将抛出“TypeError: 1 is not a function”。如果你的编码风格不使用分号,请记住,当一行以左括号开头时,在其前面加上一个分号。这种做法被一些格式化工具和/或风格指南推荐,包括 Prettier 和 standard。
const a = 1
;(1).toString()
有关处理 ASI 的更多建议,请参阅其参考部分。
规范
规范 |
---|
ECMAScript® 2026 语言规范 # sec-grouping-operator |
浏览器兼容性
加载中…