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.
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:
- Turn silent mistakes into real errors.
- Remove or fix some confusing, unsafe features.
- 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
importandexport, 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
varand relying on hoisting tricks. Strict mode does not remove hoisting. Useletandconst. - Trying to turn strict mode off. You cannot. If part of your code needs sloppy mode, keep it in a separate script.
Practice
- 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. - Freeze an object with
Object.freeze, try to change a property inside a"use strict"function, and catch the error. Printerror.name. - 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. - Fix the error from question 3 using
bind. - Write
showThis()in both modes and print whatthisis in each. - Write a function that tries to
deletea property of a frozen object in strict mode and in sloppy mode, and compare. - Show the difference between
arguments[0]and the parameter after changing the parameter, in both modes. - List 5 situations where strict mode gives an error that sloppy mode hides.
- Challenge: write a function
isStrictMode()that returnstruewhen 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 throwTypeError,thisisundefinedin plain function calls, and duplicate parameters, octal literals like010,withand reserved words as names areSyntaxErrors. - Strict mode also stops parameters from being linked to
arguments, and removesarguments.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.