javascript,

Const vs Object.freeze in JavaScript: Key Differences Explained

Krunal Krunal Follow Feb 22, 2026 · 7 mins read
Const vs Object.freeze in JavaScript: Key Differences Explained
Share this

If you write JavaScript, you’ve probably used const. You might have heard of Object.freeze too. They sound similar. Both seem to “lock” something in place. But they work in very different ways.

Getting them mixed up causes bugs that are hard to track down. This article breaks down what each one does, shows you clear examples, and helps you know when to use which.


What Does const Do?

const creates a variable that you cannot reassign. That’s it.

It does not stop you from changing the contents of an object or array. It just stops you from pointing that variable to something else.

Example

const user = { name: "Alice", age: 25 };

user.name = "Bob"; // This works fine
console.log(user.name); // "Bob"

user = { name: "Charlie" }; // Error! Cannot reassign a const variable

So const locks the binding, not the value.

Think of it like a name tag glued to a box. You can’t move the name tag to a different box. But you can change what’s inside the box all you want.


What Does Object.freeze Do?

Object.freeze stops you from changing an object’s properties. You can still reassign the variable (if it’s not const), but you can’t modify what’s inside the frozen object.

Example

let config = { theme: "dark", lang: "en" };
Object.freeze(config);

config.theme = "light"; // Silently fails in normal mode
console.log(config.theme); // Still "dark"

config = { theme: "light" }; // This works, because config is `let`

Object.freeze locks the contents, not the variable.

Going back to our box: you can move the name tag to a new box. But you can’t change what’s inside the frozen one.


Using Both Together

Most of the time, you’ll want both. Use const to stop reassignment, and Object.freeze to stop property changes.

const settings = Object.freeze({ debug: false, version: "1.0" });

settings.debug = true;   // Silently fails
settings = {};           // Error! Can't reassign const

console.log(settings.debug); // false

This gives you a truly immutable object for simple, flat data.


The Catch: Freeze is Shallow

Object.freeze only freezes the top level. Nested objects are still editable.

const app = Object.freeze({
  name: "MyApp",
  config: { debug: true }
});

app.name = "OtherApp"; // Fails, frozen
app.config.debug = false; // This WORKS! Nested object is not frozen

console.log(app.config.debug); // false

If you need deep freezing, you have to freeze each nested object yourself, or use a helper function.

Deep Freeze Example

function deepFreeze(obj) {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === "object" && obj[key] !== null) {
      deepFreeze(obj[key]);
    }
  });
  return Object.freeze(obj);
}

const app = deepFreeze({
  name: "MyApp",
  config: { debug: true }
});

app.config.debug = false; // Now this fails too
console.log(app.config.debug); // true

Does Freeze Work in Strict Mode?

In normal mode, trying to change a frozen object fails silently. No error is thrown. This can hide bugs.

In strict mode, it throws a TypeError. That’s usually what you want during development.

"use strict";

const config = Object.freeze({ env: "prod" });
config.env = "dev"; // TypeError: Cannot assign to read only property

Always use strict mode to catch these issues early.


Quick Comparison Table

Feature const Object.freeze
Blocks reassignment Yes No
Blocks property changes No Yes
Works on arrays Yes Yes
Deep freeze N/A No (shallow only)
Throws in strict mode Yes Yes

Real World Use Cases

Use const when: You want to make sure a variable always points to the same thing. This is good practice for most variables, even when you plan to mutate the object.

const users = [];
users.push("Alice"); // Fine, you're not reassigning

Use Object.freeze when: You have config data, constants, or lookup tables that should never change at runtime.

const STATUS = Object.freeze({
  PENDING: "pending",
  ACTIVE: "active",
  CLOSED: "closed"
});

Use both when: You want a fully locked object with no reassignment and no property changes.


FAQs

Q: Does const make an object immutable?
No. const only stops you from reassigning the variable. The object’s properties can still be changed.

Q: Does Object.freeze prevent reassignment?
No. If the variable uses let or var, you can still point it to a new object. Freeze only protects the contents.

Q: Can I freeze an array?
Yes. Object.freeze works on arrays too. After freezing, you can’t push, pop, or modify elements.

const colors = Object.freeze(["red", "green", "blue"]);
colors.push("yellow"); // TypeError in strict mode

Q: Is Object.freeze permanent?
Yes. Once an object is frozen, it cannot be unfrozen. There is no Object.unfreeze.

Q: Does freeze affect performance?
For most apps, the difference is too small to matter. Frozen objects can sometimes help JavaScript engines optimize code, but don’t freeze everything just for speed.

Q: How do I deeply freeze a nested object?
Write a recursive function that freezes each nested object, or use a library like deep-freeze.

Q: Should I always use const instead of let?
Use const by default. Switch to let only when you need to reassign the variable.


Summary

const and Object.freeze solve different problems. const stops you from reassigning a variable. Object.freeze stops you from changing an object’s properties.

For truly locked data, use both. And remember, freeze is shallow, so nested objects still need to be frozen separately.

Once you understand this, you’ll write cleaner, safer JavaScript and avoid a whole class of subtle bugs.

Krunal
Written by Krunal
Krunal Kanojiya is the lead editor of TechAlgoSpotlight with over 5 years of experience covering Tech, AI, and Algorithms. He specializes in spotting breakout trends early, analyzing complex concepts, and advising on the latest in technology.