Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Emily Christiansen and Simon Free and Dave Ferguson and Joel Hill and Dan Wilson and Jeff McDowell and Brian Rinaldi
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Emily Christiansen@egchristiansen ) , Simon Free@simonfree ) , Dave Ferguson@dfgrumpy ) , Joel Hill@Jiggidyuo ) , Dan Wilson@DanWilson ) , Jeff McDowell@jeff_s_mcdowell ) , and Brian Rinaldi@remotesynth )

SyntaxError: Unexpected Strict Mode Reserved Word Using Yield In Generators

By Ben Nadel on

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.

Looking For A New Job?

Ooops, there are no jobs. Post one now for only $29 and own this real estate!

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.