12 — Strict Mode — Opting Into Stricter Rules
That "use strict" line at the top of files looked like incantation until I learned what it switches. The idea that everything else hangs off: strict mode is an opt-in variant of JavaScript that converts a class of silent, error-prone behaviors into loud errors — and in modern code it's almost always already on by default. [1]
The framing that finally landed is the failure-mode view. JavaScript's original "sloppy mode" was forgiving in ways that produced bugs silently — assigning to an undeclared variable created a global, duplicate parameters were allowed, this defaulted to the global object. Strict mode's entire job is to make those mistakes throw, so I find them at the line that caused them instead of three features later.
What changes in strict mode
The list of differences is long, but a handful cover almost everything I'd actually hit [1][2]:
- Undeclared variables throw. x = 5 without let/const/var creates a global in sloppy mode; in strict mode it's a ReferenceError. The single most valuable change.
- this in plain functions is undefined, not the global object. Stops the classic bug of accidentally mutating window from a constructor called without new.
- Duplicate parameter names throw. function f(a, a) {} was silently allowed; now it's a SyntaxError.
- Deleting un-deletable properties throws. delete Object.prototype silently no-ops in sloppy mode; strict mode rejects it.
- Octal literals (010) and with statements are forbidden. Both were footguns.
- arguments and caller are cleaner. arguments.callee and arguments.caller throw, and assigning to arguments doesn't leak out.
The common thread: every change turns a silent success into a loud failure for operations that were almost certainly mistakes.
How to turn it on
Two scopes [1]:
// Whole script — must be the literal first statement
"use strict";
// everything below runs strict
// Single function
function strict() {
"use strict";
// strict here only
}The string has to be the literal first statement; it's not parsed as code — it's a directive the engine recognizes. Putting it after any other statement makes it a no-op expression.
Why I rarely write it anymore
The part that surprised me: in modern JavaScript, strict mode is on by default in the places that matter [1][2]:
- ES modules (<script type="module">, import/export, .mjs) are strict by default — no directive needed.
- Classes (class bodies) are strict by default.
- Bundlers and transpilers (most build setups) default to strict.
So the "use strict"; line is mostly a relic of pre-module scripts and legacy function-style files. I add it to standalone .js files that aren't modules (a quick utility, a bookmarklet) for safety; I omit it everywhere a module or class already enforces it.
How I use this
The habit is: assume strict mode is on (because in modules and classes it is), write code that's strict-clean anyway (always declare variables, never rely on sloppy this), and add the directive only to non-module scripts as a belt-and-suspenders measure. The payoff isn't that strict mode unlocks new features — it doesn't. The payoff is that a category of bugs I used to chase (the mystery global, the mutated window) simply stops happening, because the line that would have caused it throws instead.
References
[1] Mozilla, "Strict mode," MDN Web Docs, 2024. [Online]. Available: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
[2] I. Kantor, "The modern mode, "use strict"," The Modern JavaScript Tutorial, 2024. [Online]. Available: https://javascript.info/strict-mode
Knowledge check · Question 1 of 5
In strict mode, what happens when you assign to a variable without declaring it (x = 5)?
Comments
Leave a Comment
You must be signed in to comment
0 Comments
No comments yet. Be the first to comment!