What is the exact parsing precedence of arrow function (fat arrow =>) in Javascript?

前端 未结 2 1557
猫巷女王i
猫巷女王i 2020-12-09 09:47

I came across an example from eslint documentation on arrow function:

// The intent is not clear
var x = a => 1 ? 2         


        
2条回答
  •  鱼传尺愫
    2020-12-09 10:21

    As you say, => is not an operator. Arrow functions are primary syntax.

    The rules for them are defined in the specification, starting with the ArrowFunction production. ArrowFunction is defined as ArrowParameters followed by => followed by the misleadingly-named ConciseBody. ConciseBody has two forms. You're asking about the form using ExpressionBody, which is where the first non-whitespace token after => isn't {. If there were an opening curly brace there it would denote the opening of a block called a FunctionBody instead.

    The ExpressionBody definition is quite simple: it's an AssignmentExpression.

    Which takes us into very familiar territory, because AssignmentExpression is the syntax for the right-hand side of an assignment (or variable initializer), entries in an array initializer, the value part of a property initializer, an argument to a function, etc. So whatever follows the => in a concise body has the same parsing rules as what we put where AssignmentExpression is below:

    x = AssignmentExpression;
    y = AssignmentExpression, z = AssignmentExpression;
    a1 = [AssignmentExpression];
    a2 = [AssignmentExpression, AssignmentExpression];
    o1 = {foo: AssignmentExpression};
    o2 = {foo: AssignmentExpression, bar: AssignmentExpression};
    doSomething(AssignmentExpression);
    doSomething(AssignmentExpression, AssignmentExpression);
    

    Just for detail, an AssignmentExpression is any of:

    • ConditionalExpression (as in your example)
    • YieldExpression
    • ArrowFunction
    • AsyncArrowFunction
    • LeftHandSideExpression = AssignmentExpression
    • LeftHandSideExpression AssignmentOperator AssignmentExpression

    (You may wonder, as I did, how the y in x = y can match AssignmentExpression given the definition of it above, since y is clearly an Identifier and none of those looks like it will lead to the Identifier production. This is where specs can be really hard to read. It turns out that you get there if you keep going long enough. The path is (deep breath): AssignmentExpression → ConditionalExpression → LogicalORExpression → LogicalANDExpression → BitwiseORExpression → BitwiseXORExpression → BitwiseANDExpression → EqualityExpression → RelationalExpression → ShiftExpression → AdditiveExpression → MultiplicativeExpression → ExponentiationExpression → UnaryExpression → UpdateExpression → LeftHandSideExpression → NewExpression → MemberExpression → PrimaryExpression → IdentifierReference → Identifier — whew! [mops brow]. Thank you Oriol!)

提交回复
热议问题