Early JavaScript was designed to be forgiving: many mistakes were silently ignored instead of reported. Strict mode is an opt-in setting that turns those silent mistakes into real errors, so you find bugs right away instead of hours later.
Put the string "use strict"; as the very first statement of a script or a function:
"use strict"; // whole script is strict
let x = 5;
// ...
function careful() {
"use strict"; // only this function is strict
// ...
}
"use strict" arrived in ECMAScript 5 (2009). It was designed so that older browsers would not break: a lone string like "use strict"; is a perfectly legal expression that does nothing, just like writing "John Doe"; or 4 + 5; on a line by itself. Old browsers simply ignored it. Newer JavaScript engines recognize that exact string at the top of a script or function as a directive: an instruction about how to run the code.
Where you put it decides how much code is strict:
x = 3.14; // fine: this part is not strict
myFunction();
function myFunction() {
"use strict";
y = 3.14; // ReferenceError: only this function is strict
}
Code inside a class body and code in JavaScript modules (<script type="module">) is always strict. Most modern code is strict even when you never typed the words.
The single most useful change. Without strict mode, assigning to a misspelled name quietly creates a new global variable:
// sloppy mode
let total = 0;
totl = 50; // typo: creates a global "totl", no error
console.log(total); // 0 ...why didn't it update?
"use strict";
let total = 0;
totl = 50; // ReferenceError: totl is not defined
Strict mode points straight at the typo.
"use strict";
function whoAmI() {
return this;
}
console.log(whoAmI()); // undefined (sloppy mode: the whole window object)
Remember "losing this" from the Object this lesson? In strict mode, a lost this is undefined, so reading this.name throws a clear error instead of quietly reading something off window.
Some values cannot be changed. Sloppy mode ignores attempts to change them; strict mode reports them:
"use strict";
const settings = Object.freeze({ theme: "dark" });
settings.theme = "light";
// TypeError: Cannot assign to read only property 'theme' of object '#<Object>'
NaN = 5;
// TypeError: Cannot assign to read only property 'NaN' of object '#<Window>'
"use strict";
function add(a, a) { // SyntaxError: Duplicate parameter name not allowed
return a + a;
}
Words JavaScript might use later cannot be used as variable names:
"use strict";
let interface = 1; // SyntaxError: Unexpected strict mode reserved word
// also reserved: implements, package, private, protected, public, static, yield
| Banned in strict mode | Why |
|---|---|
| with (obj) { ... } | Made it impossible to tell which variable a name meant |
| let n = 010; | Leading-zero octal numbers were confusing (010 was 8). Use 0o10 |
| delete myVariable; | Deleting a plain variable never worked; now it is a syntax error |
| let x = "\010"; | Octal escape characters in strings, for the same reason |
| delete myFunction; | Deleting a function name is banned, like deleting a variable |
| let eval = 1; let arguments = 1; | These names are reserved for JavaScript's own use |
| obj.x = 1; (x has only a getter) | Writing to a read-only or get-only property now throws instead of failing silently |
| eval("var z = 2"); | eval can no longer create variables in the surrounding code |
this cannot silently touch the global object"use strict"; to the top of every standalone script you write. It costs nothing and every error it throws is a bug you would have had to hunt for later.
Where must "use strict"; go to take effect?
What does this function return?
function who() {
"use strict";
return this;
}
who();
undefined. In strict mode, a plain function call (no object and dot in front) gets undefined as this, instead of the global window object.Which of these is not changed by strict mode?
interface as a variable name+"use strict"; as the first line and run it again"use strict";, call it, and read the error"use strict"; on the second line of a function instead of the first, and confirm it has no effect