"use strict" in JavaScript
TL;DR:
"use strict"switches JavaScript to a safer mode. It catches silent errors, blocks risky features, and makesthisbehave predictably. ES modules andclassbodies are already strict by default.
What is "use strict"?
A special directive string that turns on strict mode for a script or a function.
"use strict"; // put at the top of a file OR inside a function
- File‑level: Must be the very first statement.
- Function‑level: Put it as the first line inside the function.
- ES Modules (
.mjs/type="module") and class bodies are always strict, no directive needed.
Why use it? It:
- Converts many silent bugs into runtime errors (so you see them early).
- Disallows dangerous features like
with. - Makes
thisin normal functionsundefinedif not bound (no more accidentalwindow/global). - Locks down
eval/argumentsbehavior for predictability.
Common JavaScript mistakes strict mode catches/changes
- Accidental globals (assigning to an undeclared variable)
"use strict";
price = 100; // ❌ ReferenceError (was creating a global in non‑strict)
- Duplicate object property names (ES5 engines)
"use strict";
const item = { id: 1, id: 2 }; // ❌ SyntaxError in older ES5 engines
- Duplicate function parameter names
"use strict";
function total(price, price) { /*...*/ } // ❌ SyntaxError
thisdefaulting to global (no more!)
"use strict";
function show() { console.log(this); }
show(); // logs undefined (✅). Non‑strict: would be the global object
- Deleting variables, functions, or non‑configurable props
"use strict";
var a = 1;
delete a; // ❌ SyntaxError
Object.defineProperty(globalThis, "x", { value: 1, configurable: false });
// delete x; // ❌ TypeError in strict (fails loudly)
- Writing to read‑only / getter‑only properties
"use strict";
const obj = {};
Object.defineProperty(obj, "ro", { value: 7, writable: false });
obj.ro = 9; // ❌ TypeError (non‑strict: silently ignored)
- Octal literals like
0123are forbidden (use0o123)
"use strict";
const n = 0123; // ❌ SyntaxError
const ok = 0o123; // ✅ 83
withis banned
"use strict";
with (Math) { // ❌ SyntaxError
console.log(random());
}
- Safer
eval(no leaking new vars to surrounding scope)
"use strict";
let x = 1;
eval("var x = 99; console.log('inner', x)"); // prints inner 99
console.log("outer", x); // prints outer 1 (unchanged) ✅
arguments/evalare reserved (no reassigning or shadowing)
"use strict";
function f(eval) {} // ❌ SyntaxError (param named eval)
arguments = 5; // ❌ TypeError
function g(a){ a = 10; console.log(arguments[0]); }
g(1); // prints 1 in strict (no aliasing); non‑strict: would print 10
- Accessing
arguments.callee/arguments.calleris forbidden
"use strict";
(function self(){ console.log(arguments.callee); })(); // ❌ TypeError
- Future reserved words are blocked
implements, interface, let, package, private, protected, public, static, yieldcannot be identifiers.
Real‑world, super simple examples (5–10 quick wins)
1) Prevent accidental global
"use strict";
function applyDiscount() {
finalPrice = 99; // ❌ typo: should be let/const
}
Fix:
let finalPrice = 0;
function applyDiscount(){ finalPrice = 99; }
2) Safer handlers with this
"use strict";
function onClick(){ console.log(this === undefined); } // true
No more accidental reliance on window. Use .bind, arrow, or call via object.
3) Catch duplicate params in an API
"use strict";
function createUser(id, id){ /*...*/ } // ❌ SyntaxError
4) No silent failure when writing to read‑only config
"use strict";
const config = {};
Object.defineProperty(config, "mode", { value: "prod", writable:false });
config.mode = "dev"; // ❌ TypeError instead of silent ignore
5) Ban with in legacy code
"use strict";
with(user){ name = "Shyam" } // ❌ SyntaxError
6) Block octal literals in price lists
"use strict";
const price = 075; // ❌ SyntaxError; use 0o75
7) Keep eval boxed
"use strict";
let token = "A";
eval("var token='B'");
console.log(token); // A ✅ (no bleed‑through)
8) Delete misuse surfaces instantly
"use strict";
var cart = 1;
delete cart; // ❌ SyntaxError
9) Block arguments tricks
"use strict";
function sum(a,b){ a=10; return a + arguments[0]; }
sum(1,2); // 20 in non‑strict; 11 in strict ✅
10) Prevent shadowing eval
"use strict";
function run(eval){ } // ❌ SyntaxError
Where strict mode applies automatically
- ES Modules:
<script type="module">or.mjsfiles are always strict. - Class bodies: everything inside
class { ... }is strict.
Best practices
- Prefer ES modules and classes; you get strict mode by default.
- If you ship legacy scripts, add
"use strict";at the top of each file. - Avoid features banned by strict mode even in non‑strict code (e.g., no
with, no octals, noarguments.callee). - Write variables with
let/const, never rely on implied globals. - Use linters (ESLint) to catch strict‑mode issues early.
FAQ (short)
- Does strict mode make code faster? Engines may optimize strict code better because semantics are simpler (no
with, fewer dynamic tricks). Treat any speedup as a bonus, not a guarantee. - Will it break old libraries? Yes, sometimes—especially ones using
arguments.callee, duplicate params, or relying onthis === window. - Node.js: ES modules (
.mjsor"type":"module") and class bodies are strict; CommonJS files need"use strict";if you want strict.
50 advanced interview questions (with crisp answers)
- What are the semantics of
thisin strict vs non‑strict functions? Strict: unboundthisisundefined; non‑strict: it’s the global object. - Why was
withbanned in strict mode? It destroys lexical predictability and blocks optimizations. - How does strict mode change
eval?evalruns in its own scope and doesn’t leak vars to the outer scope;eval/argumentscannot be reassigned or shadowed. - What happens when you assign to a read‑only property in strict mode? Throws
TypeError(non‑strict: silent no‑op). - Can you delete a variable or function in strict mode? No—
deleteon bindings is aSyntaxError. - What about deleting a non‑configurable property? Throws
TypeErrorin strict; returnsfalsein sloppy. - Do getters/setters change behavior in strict mode? Assigning to getter‑only throws in strict; silently ignored in sloppy.
- Are octal literals allowed? Legacy
0NNNliterals are banned; use0oNNN. - What are the restrictions on
argumentsin strict mode? No aliasing with parameters;arguments.callee/callerforbidden; cannot assign toarguments. - Can function parameters have duplicate names? Not in strict—
SyntaxError. - Do duplicate object properties error in strict? In ES5 engines they do; modern engines allow last‑write‑wins but linters/strict style discourage.
- How does strict mode affect
Functionconstructor? Functions created are strict only if the source includes the directive. - Does strict mode alter hoisting? Hoisting still exists; strict changes what is allowed (e.g., duplicates) but not hoist mechanics.
- How does strict mode interact with
let/constand TDZ? TDZ is ES6 spec feature independent of strict; modules (strict by default) commonly expose TDZ errors sooner. - Are
classbodies strict? Yes, always. - Are ES modules strict? Yes, always.
- How does strict mode impact performance optimizations? Simpler semantics can enable better engine optimizations; not guaranteed.
- Can you detect strict mode at runtime?
function(){ return !this; }()returnstruein strict (sincethisisundefined). - How are
thisbindings in arrow functions affected? Arrowthisis lexical; strict affects the surrounding scope’s rules, not arrow binding. - Does strict mode change JSON behavior? No; JSON parsing is the same.
- How does strict mode affect
bind/call/applywithnull/undefined?thisremainsnull/undefinedin strict; coerced to global in sloppy. - What about primitive
this(e.g., number) in function calls? In strict, primitives are not boxed forthis. - Can you declare
evalas a variable in strict? No;evalis a restricted identifier. - Is
argumentswritable? Assigning to it throws in strict. - Does strict mode change enumeration order? No.
- What is the effect on
deleteof plain names? Always aSyntaxErrorin strict. - Can you create properties on primitives implicitly? No; attempts to assign to primitives’ props have no effect, and in strict may throw in certain operations.
- How does strict mode affect
for..inorfor..of? No semantic change; but errors surface earlier (e.g., writing to RO targets). - **Are
callerandargumentsproperties on functions acces