为什么带有空箭头函数 (()=>{}) 的逻辑或运算符 (||) 会导致 SyntaxError?

IT技术 javascript arrow-functions
2021-01-21 03:52:44

在我的代码中,我有一些东西可以归结为:

var x = y || ()=>{};

(如果你想知道,我稍后会调用x()并且y可能被定义为一个函数,也可能不是,所以如果不是,我不希望抛出 TypeError。)

出于某种原因,这会导致

语法错误:意外的令牌)

为什么?我发现

var x = y || (()=>{});

工作得很好,但是

y || ()=>{}

不工作。这是指定的,还是 V8 或 Chrome 中的错误?(我仅在最新版本的 Chrome 稳定版中对此进行了测试。)

3个回答

这是正常的。function表达式不同,它像其他文字和标识符一样PrimaryExpression,而箭头函数具体是一个AssignmentExpression,并且只能出现在分组、逗号、赋值、条件(三元)和产量表达式中。任何其他运算符都会导致歧义。

例如,如果您期望y || ()=>z工作,那么也()=>z || y应该期望工作(假设对称优先级)。然而,这显然与我们可以在简洁的箭头函数体内使用任何运算符的期望相冲突。因此,这是一个语法错误,需要显式分组才能工作并保持可维护性。

这不是 JavaScript 引擎中的错误。此行为已记录在案。

尽管箭头函数中的箭头不是运算符,但与常规函数相比,箭头函数具有特殊的解析规则,与运算符优先级的交互不同。

来源:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Parsing_order

这意味着y || () => {}需要适合LogicalORExpression || LogicalANDExpressiony是一个有效的LogicalORExpression,但是LogicalANDExpression → BitwiseORExpression → BitwiseXORExpression → BitwiseANDExpression → EqualityExpression → RelationalExpression → ShiftExpression → AdditiveExpression → MultiplicativeExpression → ExponentiationExpression → UnaryExpression → UpdateExpression → LeftHandSideExpression现在,有三个选项,但最接近的是LeftHandSideExpression → NewExpression → MemberExpression → PrimaryExpression
2021-03-23 03:52:44
如果(1),那么它是x = ((y || ()) => {}); 如果(2),那么x = (y) || (() => {})但在 (1) 的情况下,ArrowFunction → ArrowParameters => ConciseBodyArrowParameters is y || (),它不是BindingIdentifier它也不是CoverParenthesizedExpressionAndArrowParameterList(简称CPE&APL),因为它缺少周围的括号。(1) 中没有替代方案。如果我们遵循(2),那么ConditionalExpression → ShortCircuitExpression → LogicalORExpressionCoalesceExpression不适合) → LogicalORExpression || LogicalANDExpression
2021-04-03 03:52:44
那些解析规则是什么?
2021-04-08 03:52:44
尝试用活的规范解析它:如果有的话,那么x = y || () => {};看起来像一个ExpressionStatement它在开始时没有任何语法阻止它进入“表达式上下文”(“前瞻”部分),所以它是一个Expression ;然后Expression → AssignmentExpression → LeftHandSideExpression = AssignmentExpression后者的AssignmentExpression现在有一个决定:是 (1) AssignmentExpression → ArrowFunction还是 (2) AssignmentExpression → ConditionalExpression
2021-04-08 03:52:44
它可能在某个地方的规范中,我现在没有时间搜索它。 ecma-international.org/ecma-262/6.0
2021-04-11 03:52:44

试试这个 var x =( y || (()=>{}));