Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at dev.Objective() 2015 (Bloomington, MN) with: Stacy London
Ben Nadel at dev.Objective() 2015 (Bloomington, MN) with: Stacy London@stacylondoner )

Strict Mode Settings In JavaScript Are Scoped To The Script Tag

By Ben Nadel on

CAUTION: This is mostly a note to self.

Yesterday, in a discussion with Sean Roberts, the lead of our Web Performance Team, I learned something new about the "use strict" mode assertion in JavaScript. Prior to our discussion, I had known that Strict Mode was scoped to Function blocks and to modules. But, I had assumed that if it were used inside of a Script tag, it would be scoped to the page in which the Script tag was included (just like every other reference in said Script tag). Sean pointed out that Strict Mode was, in actuality, scoped to Script tags as well. So, in attempt to burn this notable into the back of my mind, I wanted to see this scoping for myself.

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

In order to determine whether or not a particular Script tag is running in Strict Mode, we can try to perform an illegal action and see if the JavaScript runtime throws an error. For example, in Strict Mode, you are not allowed to "accidentally" store variables into the global scope. So, we can try to execute a method like this:

  • function sloppyMethod() {
  •  
  • accidentallyGlobalVariable = "kablamo!";
  •  
  • }

... and see if an error is thrown.

With that said, I wanted to put a Strict Script Tag and a Sloppy Script Tag next to each other in the same page and test two things:

  1. What happens if I try to execute "sloppy" code that was defined in a "strict" context.
  2. What happens if I try to execute "sloppy" code that was defined in a "sloppy" context.

Here is my test:

  • <!doctype html>
  • <html lang="en">
  • <head>
  • <meta charset="utf-8" />
  • <title>
  • Strict Mode Settings In JavaScript Are Scoped To The Script Tag
  • </title>
  • </head>
  • <body>
  •  
  • <h1>
  • Strict Mode Settings In JavaScript Are Scoped To The Script Tag
  • </h1>
  •  
  • <script type="text/javascript">
  •  
  • // !!! STRICT MODE ASSERTION HERE !!!
  • "use strict";
  •  
  • function sloppyMethod() {
  •  
  • accidentallyGlobalVariable = "kablamo!";
  •  
  • }
  •  
  • // In this test, we're going to confirm that the sloppy-method can't be invoked
  • // in the strict mode context. This test is our CONTROL case. We are expecting
  • // this try/catch to result in catch-block execution.
  • console.group( "Test One" );
  •  
  • try {
  •  
  • sloppyMethod();
  • console.log( "STRICT mode allowed sloppy method." );
  •  
  • } catch ( error ) {
  •  
  • console.log( "STRICT Mode prevented sloppy method." );
  •  
  • }
  •  
  • console.groupEnd();
  •  
  • </script>
  • <!-- ---------------------------------------------------------------------------- -->
  • <!-- ---------------------------------------------------------------------------- -->
  • <script type="text/javascript">
  •  
  • // In this test, we're going to see what happens if we take a function that was
  • // defined in a STRICT mode and try to use it in SLOPPY mode.
  • console.group( "Test Two" );
  •  
  • try {
  •  
  • sloppyMethod();
  • console.log( "SLOPPY mode allowed ORIGINAL sloppy method." );
  •  
  • } catch ( error ) {
  •  
  • console.log( "SLOPPY Mode prevented ORIGINAL sloppy method." );
  •  
  • }
  •  
  • console.groupEnd();
  •  
  • </script>
  • <!-- ---------------------------------------------------------------------------- -->
  • <!-- ---------------------------------------------------------------------------- -->
  • <script type="text/javascript">
  •  
  • function anotherSloppyMethod() {
  •  
  • anotherAccidentallyGlobalVariable = "kablamo!";
  •  
  • }
  •  
  • // In this test, we're going to see what happens if we define a NEW SLOPPY
  • // function and try to use it in SLOPPY mode. This will allow us to determine how
  • // the "use strict" assertion is scoped: to the page or to the Script tag.
  • console.group( "Test Three" );
  •  
  • try {
  •  
  • anotherSloppyMethod();
  • console.log( "SLOPPY mode allowed ANOTHER sloppy method." );
  •  
  • } catch ( error ) {
  •  
  • console.log( "SLOPPY Mode prevented ANOTHER sloppy method." );
  •  
  • }
  •  
  • console.groupEnd();
  •  
  • </script>
  •  
  • </body>
  • </html>

As you can see, the first Script Tag is using the Strict Mode assertion. It then defines a Sloppy method (in the global scope) and tries to execute it. The next Script Tag, which is implicitly using Sloppy Mode tries to execute the already-defined function. Then, the last Script Tag, which is also implicitly using Sloppy Mode, defines a new Sloppy method and then tries to execute it.

And, when we run this test in our browser, we get the following output:


 
 
 

 
 The  
 
 
 

From the second test, we can see that the "use strict" context for the first Sloppy method traveled with it, even when the original Sloppy method was used inside of a subsequent Sloppy context. So, in a sense, functions are "lexically bound" to the Strict mode.

Then, in the third test, we can see that a newly-defined Sloppy method was able to execute without error in a subsequent Sloppy context. This indicates that the Strict Mode in the first Script Tag did not "leak" out into the page context and affect other Script Tags on the same page.

I know what you're thinking: Ben, you're such a doofus, how did you not know that? Well, in retrospect, I think I misunderstood the script-concatenation problems with "use strict". I had built up a mental model that the concatenation problem had to do with the global context; but, I see now that it had to do with the single, generated Script context.


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
Oops!
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.