Skip to main content
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Jason Dean and Mark Drew
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Jason Dean Mark Drew

Strict Mode Settings In JavaScript Are Scoped To The Script Tag

By
Published in

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.

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel