SyntaxError: Unexpected Strict Mode Reserved Word Using Yield In Generators
Yesterday, while working with some asynchronous JavaScript code being managed through the use of ES6 Generators and coroutines, I was getting an error that tripped me up for a good 10-minutes. The Node.js compiler was telling me that my use of the "yield" keyword was invalid:
SyntaxError: Unexpected strict mode reserved word
The code that contained the "yield" keyword was a simple assignment operator that looked something like this:
'use strict'
function* createGenerator() {
var x = ! yield Promise.resolve( false );
}
createGenerator().next();
While there is almost nothing going on in this code, there is clearly a problem; and, it has to do with the fact that the "yield" keyword has very low precedence. Precedence determines the order in which parts of an expression are evaluated. So, components of an expression with higher precedence are evaluated sooner and components with lower precedence are evaluated later. Remember PEMDAS from your middle-school math class? Precedence is why the (M) multiplication is evaluated before the (A) addition in the following expression: "3+4*2".
The very low precedence of the "yield" operator (2) and the very high precedence of the Logical-Not operator (16) means that my expression:
! yield Promise.resolve( false )
... is actually being interpreted as:
( ! yield ) Promise.resolve( false )
... which makes the compiler think that I'm trying to use "yield" as some sort of a reference, which is not allowed in strict mode.
In order to change this interpretation of the expression, I have to use Grouping - which has the highest precedence (20) - so that the "yield" operator is correctly associated with the Promise and not with the Logical-Not operator:
! ( yield Promise.resolve( false ) )
Now, the code runs without error because it is clear that the "yield" operator applies to the Promise within the Grouping. And then, the Logical-Not operator gets applied to Grouping.
Most of the time, I use Grouping to make sure my code is explicit. I may be able to reference operator precedence in this post (thanks to the Mozilla Developer Network); but, believe you me, I don't keep these relative numbers in my head. As such, I use Grouping to ensure the code behaves the way I want it to. yield, being a somewhat magical construct in JavaScript, still trips me up. And, I'm sure it will for a while; but, at least now I'll know what this JavaScript error means the next time I see it in my Node.js application.
Want to use code from this post? Check out the license.
Reader Comments