Extra content for "Understanding the ECMAScript spec, part 2"

发布时间 · 标签: ECMAScript

Why is o2.foo an AssignmentExpression? #

o2.foo doesn’t look like an AssignmentExpression since there’s no assignment. Why is it an AssignmentExpression?

The spec actually allows an AssignmentExpression both as an argument and as the right hand side of an assignment. For example:

function simple(a) {
console.log('The argument was ' + a);
simple(x = 1);
// → Logs “The argument was 1”.
// → 1


x = y = 5;
x; // 5
y; // 5

o2.foo is an AssignmentExpression which doesn't assign anything. This follows from the following grammar productions, each one taking the "simplest" case until the last one:

An AssignmentExpresssion doesn't need to have an assignment, it can also be just a ConditionalExpression:

AssignmentExpression : ConditionalExpression

(There are other productions too, here we show only the relevant one.)

A ConditionalExpression doesn't need to have a conditional (a == b ? c : d), it can also be just a ShortcircuitExpression:

ConditionalExpression : ShortCircuitExpression

And so on:

ShortCircuitExpression : LogicalORExpression

LogicalORExpression : LogicalANDExpression

LogicalANDExpression : BitwiseORExpression

BitwiseORExpression : BitwiseXORExpression

BitwiseXORExpression : BitwiseANDExpression

BitwiseANDExpression : EqualityExpression

EqualityExpression : RelationalExpression

RelationalExpression : ShiftExpression

Almost there…

ShiftExpression : AdditiveExpression

AdditiveExpression : MultiplicativeExpression

MultiplicativeExpression : ExponentialExpression

ExponentialExpression : UnaryExpression

Don’t despair! Just a couple of more productions…

UnaryExpression : UpdateExpression

UpdateExpression : LeftHandSideExpression

Then we hit the productions for LeftHandSideExpression:

LeftHandSideExpression :

It’s not clear which production might apply to o2.foo. We just need to know (or find out) that a NewExpression doesn’t actually have to have the new keyword.

NewExpression : MemberExpression

MemberExpression sounds like something we were looking for, so now we take the production

MemberExpression : MemberExpression . IdentifierName

So, o2.foo is a MemberExpression if o2 is a valid MemberExpression. Luckily it's much easier to see:

MemberExpression : PrimaryExpression

PrimaryExpression : IdentifierReference

IdentifierReference : Identifier

o2 is surely an Identifier so we're good. o2 is a MemberExpression, so o2.foo is also a MemberExpression. A MemberExpression is a valid AssignmentExpression, so o2.foo is an AssignmentExpression too.