RHS evaluation in assignment to unresolvable reference

Take a look at the statement

undefined.prop = console.log('oops');

that in one form or another was subject of a few questions on StackOverflow.

Clearly this should throw a ReferenceError, but should it do that before or after logging "oops"? All engines seem to agree that the right-hand side of the assignment operator is evaluated first, then it throws when putting the value in the reference, in § step 5.a.i.

But wait, how is this unresolvable reference created, and why would it only throw in strict mode? I took another look at the = evaluation, and in §12.15.4 step 1.a it will evaluate the MemberExpression which in § step 3 calls RequireObjectCoercible which does throw a TypeError on the undefined value. This completion should not be ignored, both § and §12.15.4 do use ReturnIfAbrupt (or its shorthand notation). This happens before the right hand side is evaluated.
What am I missing here?

Notice that ES5.1 still was ambigously vague about completion values, the steps I just described entered the spec text in ES6.

1 Like

The order of evaluation for assignments is one of the places that engines deviate from the specification (and each other, though not in this particular example). See https://github.com/tc39/ecma262/issues/467#issuecomment-456136685.