Strict Mode: Writing Safer JavaScript
In the aviation field, pilots must follow strict procedures and checklists—even if they seem tedious, these rules prevent catastrophic errors. JavaScript's strict mode is a similar concept—it adds stricter rules and checks to the language, helping you discover potential problems early and write safer, more reliable code.
What is Strict Mode
Strict mode is a JavaScript execution mode introduced in ES5 (2009). It changes the behavior of some silent errors to throw obvious errors, disables some confusing or unsafe syntax, and reserves certain keywords for future ECMAScript versions, providing better error checking and debugging information.
In strict mode, JavaScript will:
- Convert some silent failures to throw errors
- Disable some confusing or unsafe features
- Reserve certain keywords for future ECMAScript versions
- Provide better error checking and debugging information
How to Enable Strict Mode
Enabling strict mode is very simple—just add a string literal at the top of your code:
"use strict";This directive can be used at two levels:
1. Global Strict Mode
Use it at the very beginning of a script file, and the entire file will run in strict mode:
"use strict";
// Entire file is in strict mode
let x = 10;
console.log(x);2. Function-level Strict Mode
Use it at the beginning of a function body, and only that function will run in strict mode:
function strictFunction() {
"use strict";
// This function is in strict mode
let y = 20;
console.log(y);
}
function normalFunction() {
// This function is not in strict mode
z = 30; // In non-strict mode, this creates a global variable
}Note: "use strict" must appear at the very beginning of a script or function, with only comments and whitespace before it. If placed elsewhere, it will be ignored:
// ❌ Won't take effect
let x = 10;
"use strict"; // Too late, will be treated as a regular string
// ✅ Correct
"use strict";
let y = 20;ES6 Modules Automatically Use Strict Mode
If you use ES6 modules (import/export), the entire module automatically enters strict mode, without needing explicit declaration:
// module.js
// Automatically in strict mode, no "use strict" needed
export function hello() {
console.log("Hello");
}ES6 classes also automatically run in strict mode:
class MyClass {
constructor() {
// Automatically in strict mode
this.value = 10;
}
}Main Restrictions of Strict Mode
1. Prohibit Implicit Global Variables
In non-strict mode, assigning a value to an undeclared variable automatically creates a global variable. This is a common source of bugs:
// Non-strict mode
function createUser() {
userName = "Alice"; // Creates global variable userName
}
createUser();
console.log(userName); // "Alice" (global variable accidentally created)In strict mode, this will throw an error:
"use strict";
function createUser() {
userName = "Alice"; // ReferenceError: userName is not defined
}
createUser();This forces you to explicitly declare variables:
"use strict";
function createUser() {
let userName = "Alice"; // ✅ Correct
return userName;
}2. Prohibit Deleting Variables, Functions, and Parameters
In strict mode, you cannot use delete to delete variables, functions, or function parameters:
"use strict";
let x = 10;
delete x; // SyntaxError: Delete of an unqualified identifier in strict mode
function test() {}
delete test; // SyntaxError
function doSomething(param) {
delete param; // SyntaxError
}You can delete object properties, but not non-configurable properties:
"use strict";
let obj = { name: "Alice" };
delete obj.name; // ✅ Can delete object properties
delete Object.prototype; // TypeError: Cannot delete property 'prototype' of function Object()3. Prohibit Duplicate Parameter Names
// Non-strict mode: Later parameter overrides earlier
function sum(a, a, c) {
return a + a + c; // Only uses the second a
}
console.log(sum(1, 2, 3)); // 2 + 2 + 3 = 7
// Strict mode: Syntax error
"use strict";
function sum(a, a, c) {
// SyntaxError: Duplicate parameter name not allowed
return a + a + c;
}4. Prohibit Octal Literals
// Non-strict mode: Octal representation
let num1 = 010; // 8 (decimal)
let num2 = 0888; // 888 (because it contains 8, treated as decimal)
// Strict mode: Syntax error
"use strict";
let num = 010; // SyntaxError: Octal literals are not allowed in strict mode
// ✅ Use modern octal syntax
let num = 0o10; // 8 (ES6 octal syntax)5. Prohibit Assignment to Read-only Properties
"use strict";
// Assigning to read-only property
let obj = {};
Object.defineProperty(obj, "x", { value: 42, writable: false });
obj.x = 100; // TypeError: Cannot assign to read only property 'x'
// Adding property to non-extensible object
let nonExtensible = { name: "Alice" };
Object.preventExtensions(nonExtensible);
nonExtensible.age = 30; // TypeError: Cannot add property age, object is not extensible
// Deleting non-configurable property
delete Object.prototype; // TypeError: Cannot delete property 'prototype'In non-strict mode, these operations would silently fail, making bugs difficult to discover.
6. Scope Isolation for eval
In strict mode, variables declared in eval don't pollute the external scope:
// Non-strict mode
eval("var x = 10");
console.log(x); // 10 (eval created external variable)
// Strict mode
"use strict";
eval("var y = 20");
console.log(y); // ReferenceError: y is not definedThis makes eval safer (though you should still avoid using eval).
7. this Behavior Changes
In non-strict mode, if this in a function is undefined or null, it automatically points to the global object (window in browsers):
// Non-strict mode
function showThis() {
console.log(this); // window (browser environment)
}
showThis();In strict mode, this remains as it is:
"use strict";
function showThis() {
console.log(this); // undefined
}
showThis();
// this in object methods still works normally
let obj = {
method: function () {
console.log(this); // obj
},
};
obj.method();This prevents accidental modification of the global object:
// Non-strict mode: Dangerous!
function dangerous() {
this.value = 100; // Creates global variable window.value
}
dangerous();
// Strict mode: Safe
"use strict";
function safe() {
this.value = 100; // TypeError: Cannot set property 'value' of undefined
}
safe();8. Reserved Words
Strict mode reserves some keywords for future ECMAScript versions, which cannot be used as variable names:
"use strict";
let implements = 10; // SyntaxError
let interface = 20; // SyntaxError
let let = 30; // SyntaxError
let private = 40; // SyntaxError
let protected = 50; // SyntaxError
let public = 60; // SyntaxError
let static = 70; // SyntaxError
let yield = 80; // SyntaxError9. Prohibit with Statements
// Non-strict mode: with statement (not recommended)
let obj = { a: 1, b: 2 };
with (obj) {
console.log(a); // 1
console.log(b); // 2
}
// Strict mode: Syntax error
"use strict";
with (obj) {
// SyntaxError: Strict mode code may not include a with statement
console.log(a);
}The with statement makes code difficult to understand and optimize, and should be avoided.
Real-World Application Scenarios
1. Early Error Detection
"use strict";
function calculateTotal(price, quantity) {
// ❌ Spelling mistakes are immediately discovered
totla = price * quantity; // ReferenceError: totla is not defined
return total; // This line won't execute
}
// Without strict mode, totla would become a global variable, making bugs hard to discover2. Prevent Accidental Global Variables
"use strict";
function processData(data) {
// ❌ Forgot to declare variable
result = data.map((x) => x * 2); // ReferenceError
return result;
}
// ✅ Correct
function processData(data) {
let result = data.map((x) => x * 2);
return result;
}3. Safer this Binding
"use strict";
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, ${this.name}`);
}
}
let user = new User("Alice");
let greetFn = user.greet;
// Non-strict mode: this is window, this.name is undefined
// Strict mode: this is undefined, will throw error
greetFn(); // TypeError: Cannot read property 'name' of undefined
// ✅ Correct approach: Bind this
let boundGreet = user.greet.bind(user);
boundGreet(); // Hello, Alice4. Working with Tools and Frameworks
Modern JavaScript tools and frameworks often assume strict mode:
// React component (automatically uses strict mode)
import React from "react";
function MyComponent() {
// Here is strict mode
return <div>Hello</div>;
}
// ES6 module (automatically uses strict mode)
export function myFunction() {
// Here is strict mode
}Global vs Function-level Strict Mode
Risks of Global Strict Mode
Be careful when using strict mode in entire files, especially when your code will be merged with other scripts:
// file1.js
"use strict";
// Entire file is in strict mode
// file2.js (third-party library, non-strict mode)
// Might depend on non-strict mode features
// If two files are merged, file2.js will also be affected by strict mode, potentially causing errorsRecommended Approaches
- Use ES6 modules: Automatic strict mode with isolated scopes
- Use IIFE wrapping: Create independent scope for individual files
- Or use function-level strict mode: Only enable in needed functions
// Approach 1: ES6 module (recommended)
// module.js
export function myFunction() {
// Automatic strict mode
}
// Approach 2: IIFE
(function () {
"use strict";
// Inside this IIFE is strict mode
})();
// Approach 3: Function-level
function strictFunction() {
"use strict";
// Only this function is in strict mode
}Performance Impact
Strict mode can improve performance in some cases because it:
- Disables some hard-to-optimize features (like
with,arguments.callee) - Allows JavaScript engines to make more assumptions and optimizations
- Simplifies variable lookup (no need to check global objects)
But this performance improvement is usually very small and shouldn't be the primary reason for using strict mode. The main benefits are better error checking and code quality.
Common Pitfalls
1. Forgetting to Add "use strict"
// ❌ Written after comments
// This is my script
"use strict"; // ✅ But still effective here because comments don't count
// ❌ Written after code
let x = 10;
"use strict"; // ❌ Won't take effect2. Mixing Strict and Non-strict Code
function mixed() {
// Non-strict mode
x = 10; // Creates global variable
function inner() {
"use strict";
y = 20; // ReferenceError
}
inner();
}It's best to use strict mode uniformly across the entire project (through ES6 modules).
3. Changes to arguments Object
function test(a) {
"use strict";
a = 42;
console.log(arguments[0]); // In strict mode, doesn't change with a
}
test(10); // Output: 10 (would be 42 in non-strict mode)Summary
Strict mode is JavaScript's "safety belt." Although it adds some restrictions, these restrictions help you write safer, more reliable code. In modern JavaScript development, because ES6 modules and classes automatically use strict mode, you're likely already using it without explicit declaration.
Key takeaways:
- Use
"use strict"to enable strict mode - Strict mode prohibits implicit global variables
- Prohibits duplicate parameters, octal literals, and other error-prone syntax
thisno longer automatically points to the global object- ES6 modules and classes automatically use strict mode
- Recommended to use strict mode in all new projects
- Use modern build tools and ES6 modules to automatically get strict mode benefits
Strict mode doesn't restrict your freedom; it helps you avoid common pitfalls. Like a seatbelt doesn't restrict your driving but protects you in dangerous moments, developing the habit of using strict mode is an important step toward becoming a professional JavaScript developer.