On JavaScript strict mode
ECMAScript version 5 is the latest revision of the ECMAScript programming language ratified for widespread adoption by Ecma International - the standards body responsible for figuring out what goes into the language. If you're wondering what exactly ECMAScript is and why you should be interested, it turns out that ECMAScript is standardesefor a language that the rest of the world knows as JavaScript. Strictly speaking (no pun on title intended) JavaScript and ECMAScript aren't identical. JavaScript is a dialect of ECMAScript but the differences are mostly negligible and are largely there for historical backward compatibility reasons. ECMAScript 5 (henceforth referred to as ES5) brings a suite of interesting features to the table, many of which have as their goal, the introduction of greater programming discipline to the language.
In this post (and over the next few posts), we review one such feature which directly addresses some of the more notorious parts of the language. This new feature is known as "strict mode", which briefly, is a whole new execution mode for JavaScript that causes the execution engine to run code with slightly different semantics.
What is strict mode?
"Strict mode" is a way of causing the runtime engine to interpret and execute JavaScript with different semantics than what one sees with unrestricted code. Code running in strict mode has the following characteristics:
- Excludes some syntactic and semantic features, i.e., you can't do some things that you are allowed to do otherwise
- Modifies semantics of some features, i.e., same code runs differently in strict mode compared to what happens in unrestricted mode
- An expanded list of scenarios that cause errors to be raised instead of them being silently ignored or running with assumed intent
- Applies to specific code units - i.e., you cannot have strict mode apply to all your .js files at one shot (unless you concatenate all of them of course, in which case its one code unit as far as the runtime is concerned)
The basic rationale behind strict mode is the introduction of some runtime enforced discipline to JavaScript development. I have always felt that JavaScript is far too dynamic for its own good and in my opinion, strict mode tries to address some of that excessive dynamism. Many of the tricky parts of the language that required programmer discipline are now enforced by the engine when you mark a particular code segment as "strict". Can you spot the bug in the following snippet? With "strict mode" turned on, the runtime will!
function findProduct(numbers) {
var product = 0,
len = numbers.length;
for(var i = 0; i < len; ++i) {
prodct = product * numbers[i];
}
return product;
}
Browser support
Pretty much all modern browsers support strict mode in their respective JavaScript engines. On Internet Explorer (IE) strict mode is available from version 10 onwards. You can download the latest platform preview of IE10 from the IE test drive site. All the samples in this article have been tested on IE10 platform preview 2 (IE10 PP2) using a JavaScript eval console I had put together sometime back. Selected samples have been tested on Google Chrome 14 and Firefox 7 beta as well.
Strict mode contexts
Running a piece of JavaScript under strict mode is simplicity itself. Here's an example:
"use strict";
alert("Look ma! Strict mode!");
The nice thing here is that this is perfectly valid ECMAScript 3 code as well (ES3 is the previous edition of ECMAScript. What happened to ES4? It went the way of the dodo!). An ES3 JavaScript engine will simply ignore the noop line and proceed with running the rest of the script. In fact, this sort of syntactic backward compatibility with ES3 has been a key design goal for ES5 and a surprisingly large part of the ES5 specification can be implemented completely in ES3 JavaScript. Strict mode however, is an example of an ES5 feature that perhaps cannot be implemented purely in ES3 JavaScript without additional support from the runtime.
The following kinds of JavaScript code can be made to run under strict mode:
Global code
This is basically executable code that you enter inside a
script
tag. For example:<script> "use strict"; // global strict mode code here </script>
Note that with HTML5, there is no longer a need to add the type attribute for script tags.
Eval code
Eval code that has the strict mode directive prefix:
eval("'use strict'; // strict code here");
Or is invoked from strict mode code:
"use strict"; eval("// strict code here");
Function code
Functions that have the strict mode directive prefixed before the rest of the code (putting the directive anywhere else doesn't count):
function foo() { "use strict"; // strict code here }
Functions declared in strict mode code inherit the strictness:
function foo() { "use strict"; var bar = function () { // strict code here }; bar(); }
Note that the latter case is particularly relevant when you are defining callbacks for various event handlers. Also, note that strictness does not extend across call stacks. Here's an example:
function foo() { // not strict mode even though // foo is being invoked from a // "strict" function } function bar() { "use strict"; foo(); } bar();
In the next post we'll start taking a look at some of the restrictions that ES5 strict mode imposes on the language and how they help you write better JavaScript.