Strict mode in JavaScript
Strict mode is a JavaScript mode, activated by "use strict";, that makes the engine throw errors for patterns it would otherwise accept silently.
Theory
TL;DR
- Think of it as a compiler warning system: sloppy JavaScript runs anyway, strict mode stops you before it gets bad.
- Main difference: without strict mode, assigning to an undeclared variable creates a global; with it, you get a
ReferenceErrorimmediately. thisinside a regular function call returnsundefinedin strict mode, notwindoworglobal.- ES6 modules are strict by default. No directive needed.
- Add it to every new file. The only exception: scripts targeting IE9 or older.
Quick example
// Without strict mode - creates a silent global variable
function calcTotal(price) {
subtotal = price * 1.1; // No error, but pollutes global scope
return subtotal;
}
// With strict mode - fails at the source
"use strict";
function calcTotal(price) {
subtotal = price * 1.1; // ReferenceError: subtotal is not defined
return subtotal;
}The first version runs fine and silently poisons the global object. The second stops you right where the problem is, not three functions later when something breaks in an unrelated place.
What strict mode actually changes
When the JS engine sees "use strict";, it switches to stricter parsing for that scope and all child scopes. During compilation, before any code runs, it flags octal literals (008), duplicate parameter names, and the with statement as SyntaxError. At runtime, undeclared variable assignments throw ReferenceError, and delete on a variable identifier throws SyntaxError.
The change that trips people up most: this inside a plain function call is undefined in strict mode. In sloppy mode it defaults to the global object. That default is responsible for a whole class of bugs where you write to window thinking you are writing to an object property.
When to use
- New file or project:
"use strict";at the top. No downside. - Legacy codebase: add it per-file or per-function. Migrate gradually.
- ES6 modules (
.mjs, ortype="module"in HTML): already strict. Skip the directive. - Third-party scripts you cannot control: wrap your own code in a strict IIFE instead of setting global strict.
- The real exception: scripts that must run in IE9 or older.
How the engine handles it
V8 in Chrome and Node.js applies more aggressive JIT optimizations to strict code. The reason: no with statement to complicate scope resolution, no implicit globals, predictable this. In Node.js, pass --use-strict to enable it globally. Babel and webpack add "use strict" automatically when transpiling with @babel/preset-env.
Common mistakes
Assuming function-level strict affects the caller:
function parent() {
x = 1; // No error - parent is in sloppy mode
}
function child() {
"use strict";
y = 2; // ReferenceError - child is strict
}Strict mode applies only to its own scope. The parent stays sloppy. This creates confusion in codebases where only some files have the directive.
Trying to delete a variable:
"use strict";
var total = 100;
delete total; // SyntaxError: Delete of an unqualified identifier in strict modeIn sloppy mode, delete on a variable silently returns false. In strict mode it is a SyntaxError.
Expecting eval() to inherit strict mode:
"use strict";
eval("x = 1"); // Still pollutes global scope - eval needs its own directive
// Fix:
eval('"use strict"; x = 1;');Common Node.js gotcha that appears regularly in interview scenarios.
Duplicate parameter names:
"use strict";
function add(a, a) { // SyntaxError before any code runs
return a + a;
}Sloppy mode accepts this without a word. Strict mode catches it at parse time.
Real-world usage
- React: Babel adds
"use strict"to every transpiled file via@babel/preset-env. - Node.js: core modules like
fsuse strict internally. Yourapp.jsshould too. - Express: production starters set strict at file level to prevent global leaks in route handlers.
- Lodash: strict mode since v4.0, which removed a category of prototype-related issues.
- jQuery: v3+ runs in strict mode.
I have seen global variable leaks from Express route handlers cause memory issues in Node.js production environments. Strict mode would have caught those assignments at startup, not three weeks later in a postmortem.
Follow-up questions
Q: What does "use strict" do to this in a regular function call?
A: Sets it to undefined instead of the global object. So this.name = "x" inside that function throws TypeError, instead of silently adding name to window.
Q: How do you enable strict mode in ES6 modules?
A: You do not. All ES6 modules are strict by default. Class bodies are strict too.
Q: Name three things strict mode bans.
A: Octal literals (08), duplicate parameter names, and the with statement. Also variable deletion and undeclared variable assignments.
Q: Can you mix strict and sloppy code in the same project?
A: Yes. Strict mode is per-scope. A sloppy function that calls a strict function stays sloppy on its own side. The mistake is assuming strict propagates upward to callers.
Q: Does strict mode affect performance?
A: Slightly positive. V8 applies more aggressive JIT optimizations in strict code because there are fewer edge cases in scope resolution. Small effect, but real.
Examples
Basic: undeclared variable enforcement
"use strict";
function processOrder(amount) {
// Without a declaration this would silently become a global
total = amount * 1.2; // ReferenceError: total is not defined
return total;
}
processOrder(100);The error points exactly to the missing const or let. Without strict mode, total lands on window and you spend time tracking it across multiple files.
Intermediate: this in a detached function call
"use strict";
const obj = {
name: "strictObj",
method() {
// Arrow function: this is lexically bound to obj
return () => this.name;
},
looseMethod() {
// Regular function: this depends on how it is called
return function() { return this.name; };
}
};
console.log(obj.method()()); // "strictObj" - arrow preserves this
console.log(obj.looseMethod()()); // undefined in strict mode (window.name in sloppy)looseMethod returns a plain function called without a receiver. Sloppy mode gives it window. Strict mode makes it undefined, which exposes the bug instead of hiding it behind the global object.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.