Skip to content

JavaScript Tutorial Objects

JavaScript Object.freeze and Object.seal

Lesson 85 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

const stops a variable from being reassigned, but the object inside can still change. Object.freeze() locks the object itself.

script.js
JS
const config = Object.freeze({ apiUrl: "https://example.com", retries: 3 });

config.retries = 10;        // ignored (an error in strict mode)
config.newKey = "x";        // ignored
delete config.apiUrl;       // ignored

console.log(config);                    // → { apiUrl: https://example.com, retries: 3 }
console.log(Object.isFrozen(config));   // → true

In normal scripts, changes to a frozen object are silently ignored. In strict mode (modules, classes, "use strict"), they throw a TypeError, which is easier to notice.

Freeze is shallow

Nested objects are not frozen.

script.js
JS
const settings = Object.freeze({ theme: "dark", panel: { open: true } });

settings.panel.open = false;      // works!
console.log(settings.panel.open); // → false

To freeze deeply, freeze each nested object, for example with a small recursive function.

script.js
JS
function deepFreeze(obj) {
  Object.values(obj).forEach(value => {
    if (typeof value === "object" && value !== null) deepFreeze(value);
  });
  return Object.freeze(obj);
}

const settings = deepFreeze({ theme: "dark", panel: { open: true } });
settings.panel.open = false;
console.log(settings.panel.open); // → true

Seal and preventExtensions

MethodAdd propertiesDelete propertiesChange values
Object.preventExtensions(o)NoYesYes
Object.seal(o)NoNoYes
Object.freeze(o)NoNoNo
script.js
JS
const sealed = Object.seal({ a: 1 });
sealed.a = 2;      // allowed
sealed.b = 3;      // ignored
console.log(sealed); // → { a: 2 }

Frozen arrays

Arrays can be frozen too: push, pop and friends then throw.

script.js
JS
const days = Object.freeze(["mon", "tue"]);
try {
  days.push("wed");
} catch (error) {
  console.log(error.name); // → TypeError
}

When to use it

Freezing is useful for constants such as configuration, lists of options and values shared between modules, where accidental changes would be a bug. Do not freeze everything: it adds noise, and a non-mutating style (spread, map, filter) usually protects you well enough.