What is JavaScript 'use strict' Mode and How Does It Work? [With Examples]
A feature of ECMASCript 5, standardized sometime in the 2009 time frame, is strict mode. When enabled the JavaScript engine evaluates the script with more restrictions. Sloppy code that normally would not trigger explicit exceptions will now cause the code to throw exceptions in the evaluation step, before it is used.
John Resig explained strict mode when it was introduced:
Strict Mode is a new feature in ECMAScript 5 that allows you to place a program, or a function, in a 'strict' operating context. This strict context prevents certain actions from being taken and throws more exceptions...
This is good news because JavaScript allows many 'poor coding' practices without triggering exceptions. This can lead to pages, components and entire applications failing once they are shipped to production because developers were unaware they had improperly used syntax or a bad pattern.
Often these mistakes are innocent consequences of the development process. For example using undeclared variables due to typos or trailing commas when there are no more array items.
var myArray = [1,2,3,4,];
When strict mode was introduced development environments were not as robust as they are today. Environments like Visual Studio Code, Sublime, etc ship with some form of JavaScript linting built in. TypeScript and ESLint are also good utilities that can perform live analysis and highlight syntax and code quality issues.
Even with good modern development experiences I still think it is a best practice to use JavaScript strict mode because it triggers the syntax checking in the real environment, the browser or nodejs. This means you can see more issues that may arise from slight variations between JavaScript engines.
Why Enable JavaScript Strict Mode?
- Eliminates some JavaScript silent errors or bloopers by changing them to throw errors.
- Fixes mistakes that make it difficult for JavaScript engines to perform optimizations.
- Prohibits use of potential reserved words likely to be defined in future versions of ECMAScript.
- It prevents, or throws errors, when relatively 'unsafe' actions are taken (such as gaining access to the global object).
- It disables features that are confusing or poorly thought out, like the use of eval.
- Makes it easier to write "secure" JavaScript.
How to Enable JavaScript Strict Mode
To enable JavaScript Strict Mode just add the "use strict"; literal expression to either the beginning of a script or within a function. If you add it to the 'top' of a script the mode is triggered for the entire script is executed in strict mode. If placed within a function strict mode is limited to the function's scope.
"use strict";
or
function myFunc(){ "use strict"; //code checked by strict mode goes here }
JavaScript Strict Mode Support
This is a very safe feature to use. Every modern browser and node supports and has supported strict mode for years. If the browser does not support strict mode the expression is simply ignored. It is just a string followed by a semi-colon, a perfectly legal JavaScript statement.
What Strict Mode Breaks
I hate to use the word breaks, but it literally does break your code when strict mode is enabled. Instead of the JavaScript engine letting your sloppy code go about its business, exceptions are thrown and errors reported. Basically your code blows up as soon as it is loaded.
So what breaks?
This is a pretty good list of example scenarios, with some explanation thrown in here and there.
Undeclared Variables
"use strict"; misppeledVar = "must be a typo"; //ReferrenceError
Can't Delete Variables, Functions or Objects
"use strict"; var x = 3.14; delete x; // This will cause an error
Duplicate Parameter Names Not Allowed
I am not sure why you would do this, but I can see how an inadvertent typo can be the cause.
function sum(a, a, c) { // !!! syntax error 'use strict'; return a + a + c; // wrong if this code ran }
Duplicate Object Properties Are Not Allowed
ECMAScript allows you to declare a property name more than once. Only the last declaration is used for the value. While benign on the surface it can lead to bugs due to the vector structure used to define objects.
'use strict'; var o = { p: 1, p: 2 }; // !!! syntax error
Octal Literals and Escaped Characters Not Allowed
Sometimes developers pad numbers with leading 0s, but this is incorrect. Octal numbers are declared with a leading 0.
Strict mode forces you to be more explicit with this declaration by requiring a leading 0o in front of the octal value.
"use strict"; var x = 010; // This will cause an error var y = "\010"; // This will cause an error var z = o010;
Can't Write to Read-Only Properties
"use strict"; var objX = {}, objY = {get x() {return 0} }; Object.defineProperty(objX, "x", { value:0, writable:false }); objX.x = 3.14; // This will cause an error objY.x = 3.14; // This will cause an error
Can't Delete an Undeletable Property
"use strict"; delete Object.prototype; // TypeError
String eval Can't Be Used as a Variable
"use strict"; var eval = 3.14; // This will cause an error
Reserved Words Can't Be Used as a Variable
"use strict"; var arguments = 3.14; // This will cause an error
Can't Use the with Statement
The problem with with is that any name inside the block might map either to a property of the object passed to it, or to a variable in surrounding (or even global) scope, at runtime: it's impossible to know which beforehand.
'use strict'; var x = 17; with (obj) { // !!! syntax error // If this were not strict mode, would this be var x, or // would it instead be obj.x? It is impossible in general // to say without running the code, so the name can not be // optimized. x; }
Can't Add/Set Properties on Primitive Types
Primitive types are numbers, strings, boolean, etc. There are typically native properties, like string's toLowerCase(), which makes them fell like an object. But they are not objects, they are immutable, except for their value.
'use strict'; false.true = ''; // TypeError (14).sailing = 'home'; // TypeError 'with'.you = 'far away'; // TypeError
Can't Assign Values to Non-Writable Variables
Because JavaScript is 'flexible' you can set any variable to any value. However this can cause serious issues when you overwrite native objects.
For example a common security concern is referencing undefined, a native JavaScript value. If a third party script changes the value of undefined it can have rippling affects through out your application.
"user strict"; undefined = function(){}; //throws TypeError
Future Reserved Words Cannot Be Used
The folks standardizing ECMAScript have a decent idea where the language is going. Thus they know what words will likely become reserved.
To keep us from using these words as variable names strict mode forbids the use of these words. This means your code will not break once these new features ship. For example, var, let and const have not been allowed in strict mode, today it is a common way to declare a local variable.
- implements
- interface
- let
- package
- private
- protected
- public
- static
- yield
"use strict"; var let = 1500; // This will cause an error
Wrapping it Up
Strict mode is a way to ensure your code is clean and avoids common syntax errors before you ship. By using JavaScript strict mode you and your team should be able to find and fix common coding problems and typos before shipping to your customers.
It is not a magic bullet to identify all your bugs before you ship. You will still need to text your pages and apps for logic issues, sorry!