JavaScriptIntermediate

JavaScript Strict Mode: use strict, Rules and Restrictions

Learn JavaScript strict mode: how to enable use strict, what it changes, the common restrictions, and why modern code should use it, with clear examples.

All JavaScript lessons

What you will learn

JavaScript was created in 10 days, and in its early years it was very forgiving. If you made a typing mistake, it often did not complain and kept going, which made bugs very hard to find. To fix this without breaking old websites, JavaScript got an optional safer mode called strict mode. In this lesson you will learn what strict mode is, how to turn it on, the main things it changes, the restrictions you must know, and why you almost always get it for free in modern projects.

The problem: silent mistakes

Look at this code:

function calculate() {
  totl = 100;          // typo! you meant "total", and there is no let/const
  return totl * 2;
}

console.log(calculate());   // 200 (it works!)
console.log(totl);          // 100 (an accidental GLOBAL variable was created)

JavaScript did not warn you. It quietly created a global variable called totl. In a big project, accidents like this create bugs that take hours to find. Strict mode turns many of these silent mistakes into clear errors.

What is strict mode?

Strict mode is a stricter version of JavaScript with a few rules that:

  1. Turn silent mistakes into real errors.
  2. Remove or fix some confusing, unsafe features.
  3. Prepare your code for future JavaScript versions.

The normal, forgiving mode has an unofficial name: sloppy mode.

How to turn on strict mode

Write the text "use strict" as the first statement of a script or of a function.

For a whole script

"use strict";

let name = "Riya";
// everything in this file now follows the strict rules

For one function only

function safeFunction() {
  "use strict";
  // only the code inside this function is strict
}

function normalFunction() {
  // this one is still in sloppy mode
}

Important rules about "use strict"

  • It must be the first statement (only comments may come before it). If it is placed after other code, it is just an ordinary text and does nothing.
  • It is a plain text on purpose: old browsers that do not know it simply ignore it.
  • Single or double quotes both work: 'use strict' or "use strict".
  • There is no way to turn it off inside the same scope once it is on.
let a = 1;
"use strict";    // too late: this is NOT the first statement, so it does nothing

b = 2;           // still allowed (sloppy mode)

Strict mode is already on in modern code

You will often get strict mode automatically, without writing anything:

Place Strict by default?
A script with <script type="module"> Yes
Files you import or export (ES modules) Yes
Code inside a class body Yes
Projects built with Astro, React, Vite, Next.js and similar tools Yes (they use modules)
A plain <script> tag or a plain .js file No (sloppy mode)
Code you type in the browser console No

Good to know: if you write modern code with import and export, you are already in strict mode. Knowing the rules helps you understand the errors you will see.

The main changes in strict mode

1. You must declare your variables

"use strict";

// total = 100;     // ReferenceError: total is not defined
let total = 100;    // correct

This single rule catches most typing mistakes.

2. Silent failures become errors

In sloppy mode, some actions fail silently. In strict mode they throw a TypeError.

"use strict";

const settings = Object.freeze({ theme: "dark" });

// settings.theme = "light";   // TypeError: Cannot assign to read only property 'theme'
// settings.size = 10;         // TypeError: Cannot add property size, object is not extensible
// delete settings.theme;      // TypeError: Cannot delete property 'theme'

Other examples of actions that become errors:

"use strict";

const user = {
  get fullName() { return "Riya Sharma"; }
};

// user.fullName = "Other";    // TypeError: only a getter, no setter

// undefined = 5;              // TypeError: Cannot assign to read only property 'undefined'
// NaN = 10;                   // TypeError
// "abc".length = 1;           // TypeError: Cannot assign to read only property 'length'
// (5).color = "red";          // TypeError: Cannot create property on a number

3. this is undefined in normal functions

In sloppy mode, a function called on its own gets this pointing at the global object (window in the browser). That is dangerous because you can change global things by accident. In strict mode, this stays undefined.

function showThis() {
  return this;
}

function showThisStrict() {
  "use strict";
  return this;
}

console.log(showThis() === globalThis);   // true  (sloppy: the global object)
console.log(showThisStrict());            // undefined

This matters when a method loses its object:

"use strict";

const user = {
  name: "Riya",
  greet() {
    return "Hello, " + this.name;
  }
};

console.log(user.greet());     // "Hello, Riya"

const detached = user.greet;   // copy the method out of the object

// detached();                 // TypeError: Cannot read properties of undefined (reading 'name')

In sloppy mode, the broken call would quietly return "Hello, " (an empty name from window.name). In strict mode, you get a loud error that points straight at the problem.

4. No duplicate parameter names

"use strict";

// function add(a, a) { }    // SyntaxError: Duplicate parameter name not allowed
function add(a, b) { return a + b; }

5. No octal numbers with a leading zero

"use strict";

// let n = 010;        // SyntaxError: Octal literals are not allowed
let ok = 0o10;         // 8 (the correct way to write an octal number)

6. delete only works on object properties

"use strict";

let x = 10;
// delete x;                  // SyntaxError: Delete of an unqualified identifier

const obj = { a: 1 };
delete obj.a;                 // fine: deleting a property
console.log(obj);             // {}

7. with is not allowed

The old with statement is removed in strict mode (it made code unpredictable):

"use strict";

// with (Math) { console.log(PI); }   // SyntaxError: Strict mode code may not include a with statement
console.log(Math.PI);                 // use the object name instead

8. Reserved words cannot be variable names

Words reserved for the future language cannot be used as names:

"use strict";

// let package = 1;      // SyntaxError
// let interface = 2;    // SyntaxError
// let private = 3;      // SyntaxError
// let static = 4;       // SyntaxError
// let yield = 5;        // SyntaxError
// let let = 6;          // SyntaxError

The full list: implements, interface, let, package, private, protected, public, static, yield.

9. Changing a parameter does not change arguments

function sloppy(a) {
  a = 99;
  return arguments[0];
}

function strict(a) {
  "use strict";
  a = 99;
  return arguments[0];
}

console.log(sloppy(1));   // 99 (arguments is linked to the parameter)
console.log(strict(1));   // 1  (no link, easier to understand)

10. eval keeps its own variables

Code run by eval cannot create variables in the surrounding scope in strict mode. (You should avoid eval anyway.)

11. arguments.callee is not allowed

"use strict";

function test() {
  // return arguments.callee;   // TypeError
}

Summary table: sloppy vs strict

Situation Sloppy mode Strict mode
Assigning to an undeclared variable Creates a global ReferenceError
Changing a read-only property Silently ignored TypeError
Adding a property to a frozen object Silently ignored TypeError
Deleting a non-deletable property Returns false TypeError
this in a normal function call The global object undefined
Duplicate parameter names Allowed SyntaxError
Octal like 010 Allowed (is 8) SyntaxError
with statement Allowed SyntaxError
Reserved words as names (package, static…) Allowed SyntaxError
Parameter linked to arguments Yes No

Real-life use cases

1. Catching a typing mistake early

"use strict";

function calculateTotal(prices) {
  let total = 0;
  for (const price of prices) {
    // totl += price;      // would be ReferenceError in strict mode: you find the typo at once
    total += price;
  }
  return total;
}

console.log(calculateTotal([10, 20, 30]));   // 60

2. Finding a lost this

When you pass a method as a callback, this is lost. Strict mode shows you immediately:

"use strict";

const counter = {
  count: 0,
  increase() {
    this.count++;
  }
};

const run = counter.increase;

try {
  run();   // lost this
} catch (error) {
  console.log(error.name);   // "TypeError"
}

// Fix: keep the object with bind or an arrow function
const fixed = counter.increase.bind(counter);
fixed();
console.log(counter.count);   // 1

3. Protecting constants and configuration

"use strict";

const CONFIG = Object.freeze({ apiUrl: "https://api.example.com", retries: 3 });

try {
  CONFIG.retries = 10;
} catch (error) {
  console.log("Blocked:", error.name);   // "TypeError"
}

console.log(CONFIG.retries);   // 3

In sloppy mode this change would just be ignored with no message, and you might believe it worked.

4. Strict mode inside one old function only

If you add a safe function to an old file full of sloppy code, put "use strict" inside that function. It will not affect the rest:

function modernHelper(list) {
  "use strict";
  return list.map((item) => item * 2);
}

console.log(modernHelper([1, 2, 3]));   // [2, 4, 6]

5. Safe <script> in HTML

<script>
  "use strict";
  // all the code in this script tag is strict
</script>

<script type="module">
  // modules are strict automatically, no need to write it
</script>

6. A quick check: am I in strict mode?

function isStrict() {
  return this === undefined;
}

console.log(isStrict());   // false in sloppy mode (this is the global object)

Should you use it?

Yes. For any new code, use strict mode. In practice that means:

  • Use ES modules (import / export) or a framework, and you are strict automatically.
  • In a plain script, write "use strict"; at the very top.
  • Do not add "use strict" at the top of a script that is joined with other scripts (some old build tools merge files), because it could switch strict mode on for code that was not written for it. Put it inside functions in that case.

One more rule: a function with non-simple parameters (default values, rest, destructuring) cannot contain its own "use strict" directive. Put it at the top of the file instead.

Common mistakes

  • Writing "use strict" too late. It must be the first statement. Anything before it (except comments) makes it useless.
  • Thinking the directive is a function or setting. It is just a text that JavaScript recognises.
  • Forgetting that modules and classes are already strict, and then being surprised by an error that “does not appear” in the console. Remember that the console is sloppy.
  • Testing strict-mode errors in the browser console and getting different results. Test inside a script or a module.
  • Expecting strict mode to fix your bugs. It only makes some mistakes visible. You still need to fix them.
  • Putting "use strict" at the top of a merged file that contains old code. Use it per function there.
  • Using var and relying on hoisting tricks. Strict mode does not remove hoisting. Use let and const.
  • Trying to turn strict mode off. You cannot. If part of your code needs sloppy mode, keep it in a separate script.

Practice

  1. Write a function that assigns to an undeclared variable. Run it once without strict mode and once with "use strict" inside the function. Compare the results.
  2. Freeze an object with Object.freeze, try to change a property inside a "use strict" function, and catch the error. Print error.name.
  3. Create an object with a method that uses this.name. Copy the method into a variable, call it in strict mode, and explain the error.
  4. Fix the error from question 3 using bind.
  5. Write showThis() in both modes and print what this is in each.
  6. Write a function that tries to delete a property of a frozen object in strict mode and in sloppy mode, and compare.
  7. Show the difference between arguments[0] and the parameter after changing the parameter, in both modes.
  8. List 5 situations where strict mode gives an error that sloppy mode hides.
  9. Challenge: write a function isStrictMode() that returns true when the code around it is strict, without taking any arguments.

Recap

  • Strict mode is a safer way to run JavaScript. It turns many silent mistakes into real errors.
  • Turn it on with "use strict"; as the first statement of a script or a function.
  • ES modules (import/export) and class bodies are strict automatically, and so is most modern project code.
  • In strict mode: undeclared variables throw ReferenceError, changes to read-only or frozen things throw TypeError, this is undefined in plain function calls, and duplicate parameters, octal literals like 010, with and reserved words as names are SyntaxErrors.
  • Strict mode also stops parameters from being linked to arguments, and removes arguments.callee.
  • Always use strict mode for new code. You can never turn it off inside the same scope.
  • Next you will learn debugging and browser DevTools: how to find and fix the errors that strict mode shows you.