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.