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 §6.2.4.9 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 §12.3.2.1 step 3 calls RequireObjectCoercible which does throw a TypeError on the undefined value. This completion should not be ignored, both §12.3.2.1 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.

3 Likes