Skip to content

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:

javascript
"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:

javascript
"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:

javascript
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:

javascript
// ❌ 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:

javascript
// module.js
// Automatically in strict mode, no "use strict" needed
export function hello() {
  console.log("Hello");
}

ES6 classes also automatically run in strict mode:

javascript
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:

javascript
// 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:

javascript
"use strict";

function createUser() {
  userName = "Alice"; // ReferenceError: userName is not defined
}

createUser();

This forces you to explicitly declare variables:

javascript
"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:

javascript
"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:

javascript
"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

javascript
// 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

javascript
// 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

javascript
"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:

javascript
// 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 defined

This 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):

javascript
// Non-strict mode
function showThis() {
  console.log(this); // window (browser environment)
}

showThis();

In strict mode, this remains as it is:

javascript
"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:

javascript
// 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:

javascript
"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;       // SyntaxError

9. Prohibit with Statements

javascript
// 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

javascript
"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 discover

2. Prevent Accidental Global Variables

javascript
"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

javascript
"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, Alice

4. Working with Tools and Frameworks

Modern JavaScript tools and frameworks often assume strict mode:

javascript
// 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:

javascript
// 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 errors
  1. Use ES6 modules: Automatic strict mode with isolated scopes
  2. Use IIFE wrapping: Create independent scope for individual files
  3. Or use function-level strict mode: Only enable in needed functions
javascript
// 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"

javascript
// ❌ 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 effect

2. Mixing Strict and Non-strict Code

javascript
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

javascript
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
  • this no 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.