JavaScript Strict Mode Table

ChangeSloppy modeStrict mode
undeclared = 5Creates a global variableThrows ReferenceError - typos become loud
delete variableSilently fails (returns false)Throws SyntaxError
duplicate parameter namesLast one winsThrows SyntaxError
with (obj) { ... }AllowedThrows SyntaxError - scope games banned
this in standalone fnGlobal object (window)undefined - no accidental global writes
octal literals (0777)Allowed (as legacy)Throws SyntaxError - use 0o777
arguments.calleeWorksThrows TypeError - recursion by name instead
Reference: the MDN strict mode reference. Strict mode is opt-in ('use strict' at the top), but ES modules and class bodies are ALWAYS strict - new code is strict by default. The changes are all conversions from silent failure to loud error: accidental globals throw, silent delete failures throw, and this in standalone functions stops pointing at window. Bottom line: the TDZ, the strict this, and the duplicate-parameter throw are all the same design principle - the engine tells you at the mistake, not three bugs later. Related tools: JS error table (the errors strict mode throws), hoisting table (the scope model strict mode clarifies), and classes table (always strict inside).

Strict mode converts JavaScript's silent failures into loud errors. Turn it on with 'use strict' at the top, and seven categories of mistake that sloppy mode silently accepts become immediate throws. ES modules and class bodies are always strict - new code is strict by default.

Bottom line: every strict mode change is the same design principle - the engine tells you AT the mistake, not three bugs later. Accidental globals throw ReferenceError; silent delete failures throw TypeError; standalone this stops pointing at window (killing accidental global writes through this). The TDZ from let/const is the same philosophy: loud at the source.

The honest part: strict mode is opt-in in scripts but mandatory in ES modules and class bodies. You are almost certainly already writing strict code - the question is whether you know which of your patterns it bans, and why each ban makes debugging faster. The table's seven changes cover the differences that affect real code.

How to use

  1. Add 'use strict' at the top of a script or function body; modules and classes are already strict.
  2. Fix what the engine flags: undeclared assignments, duplicate params, octal literals - each was a real bug class.
  3. Know the with-statement ban: it makes scope unpredictable, which is why it is the only statement strict mode bans outright.

Frequently asked questions

Why does strict mode ban assigning to undeclared variables?

Because that assignment is almost always a TYPO: x = 5 when you meant bar.x = 5 or const x = 5. In sloppy mode the engine silently creates a global variable - polluting the shared namespace and potentially clobbering someone else's value. In strict mode the engine throws a ReferenceError at the exact line, turning a silent namespace pollution into an immediate fix. The fix is always: declare the variable with let, const, or var first.

What does 'use strict' actually change about this?

In sloppy mode, a standalone function call gives this as the global object (window in browsers) - so this.x = value inside a bare function silently writes to window. In strict mode, this in the same call is undefined - writing this.x throws a TypeError. This is the strict-mode version of the TDZ principle: the engine refuses to let you write to something that does not exist, instead of silently creating it.

Why are duplicate parameter names banned in strict mode?

Because with two same-named parameters, the second silently overwrites the first - arguments[0] and arguments[1] disagree with the named parameters, and the function body reads the overwritten value. In sloppy mode this is a confusing but non-crashing bug; in strict mode it is a SyntaxError caught before the function runs. The fix: rename the parameter, or use rest parameters (...args) if the function genuinely takes a variable list.

Are ES modules always strict?

Yes - all ES module code (import/export) runs in strict mode automatically, as do class bodies. You cannot opt out. This means the seven changes in the table are always active in your module code: no accidental globals, no duplicate parameters, no with statement, no octal literals. Script code (non-module) must opt in with the 'use strict' directive, but modules get it for free - which is one reason the module system makes code safer by default.

Related tools