Suggest an editImprove this articleRefine the answer for “Object.freeze() in JavaScript”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Object.freeze()` freezes an object: after the call you cannot overwrite, add or delete any property, nor change the `writable` and `configurable` descriptors.** The method returns the same object, not a copy, and you can check the state with `Object.isFrozen(obj)`. Importantly, the freeze is shallow: nested objects stay mutable, so full immutability needs a recursive `deepFreeze()`. ```javascript const user = { name: 'Alice', age: 25 }; Object.freeze(user); user.name = 'Oleh'; // will not change console.log(user); // { name: 'Alice', age: 25 } ``` **Key point:** `Object.freeze()` makes an object immutable, but only at the top level.Shown above the full answer for quick recall.Answer (EN)Image**`Object.freeze()` is a built-in JavaScript method that "freezes" an object and makes it fully immutable: properties cannot be changed, deleted or added.** The method returns the same object rather than a copy, and it only applies to the top level of the structure. ## Theory ### TL;DR - `Object.freeze(obj)` makes an object immutable and returns **the same** object. - You cannot **overwrite**, **add** or **delete** properties. - You cannot change the `configurable` and `writable` descriptors. - To check the state: `Object.isFrozen(obj)`. - The freeze is **shallow**: nested objects stay mutable. - `Object.seal()` forbids adding and deleting but allows changing values; `Object.preventExtensions()` only forbids adding new properties. ### Quick example ```javascript const user = { name: 'Alice', age: 25 }; Object.freeze(user); user.name = 'Oleh'; // will not change user.city = 'Kyiv'; // cannot add a new one delete user.age; // cannot delete console.log(user); // { name: 'Alice', age: 25 } ``` ### Syntax and checking the state ```javascript Object.freeze(obj) ``` | Argument | Description | | --- | --- | | `obj` | The object to "freeze" | The method returns **the same object**, now with frozen properties, so `const frozen = Object.freeze(user)` gives you not a copy but a second name for `user`. After `Object.freeze()` the object becomes **immutable**: - properties cannot be overwritten; - they cannot be deleted, and new ones cannot be added; - `configurable` and `writable` cannot be changed. You can check the state with a separate method: ```javascript console.log(Object.isFrozen(user)); // true ``` The execution mode matters: in ordinary (sloppy) code a write attempt is silently ignored, while under `'use strict'` or inside an ES module it throws a `TypeError`. That is exactly why the bug is easy to miss in an old script and immediately visible in a modern module. ### The freeze is shallow If there are **nested objects** inside, they **stay mutable**: ```javascript const user = { name: 'Alice', address: { city: 'Kyiv' } }; Object.freeze(user); user.address.city = 'Lviv'; // this works console.log(user.address.city); // "Lviv" ``` So `Object.freeze()` protects **only the top level**. What is frozen is the reference to `address`: you cannot replace it with another object, but you are free to change something inside that same object. For a "deep" freeze you have to freeze recursively. ### Deep freeze ```javascript function deepFreeze(obj) { Object.freeze(obj); for (const key in obj) { if (typeof obj[key] === 'object' && obj[key] !== null && !Object.isFrozen(obj[key])) { deepFreeze(obj[key]); } } return obj; } const user = { name: 'Alice', address: { city: 'Kyiv' } }; deepFreeze(user); user.address.city = 'Lviv'; // will not change console.log(user.address.city); // "Kyiv" ``` Now the object and all of its contents are completely "frozen". The `!Object.isFrozen(obj[key])` check is not only about speed: without it a circular reference (`a.self = a`) would cause infinite recursion. ### freeze, seal and preventExtensions | Method | What it does | Can you change values | Can you add or delete properties | | --- | --- | --- | --- | | `Object.freeze()` | Freezes completely | No | No | | `Object.seal()` | Forbids adding and deleting but allows changing values | Yes | No | | `Object.preventExtensions()` | Forbids adding new properties | Yes | Adding no, deleting existing ones yes | An example of `freeze` versus `seal`: ```javascript const user = { name: 'Alice' }; Object.seal(user); user.name = 'Oleh'; // allowed delete user.name; // not allowed Object.freeze(user); user.name = 'Max'; // not allowed ``` Summary table: | Property | Behaviour | | --- | --- | | `Object.freeze()` | makes the object completely immutable | | Forbidden | adding, deleting or changing properties | | Works shallowly | nested objects stay mutable | | Check | `Object.isFrozen(obj)` | ### Common mistakes - **Assuming the whole object graph is frozen.** `Object.freeze()` protects only the top level; an array inside a frozen object happily accepts `push()`. - **Counting on an error when writing.** In sloppy mode an assignment to a frozen property silently does nothing, so the bug survives unnoticed until you move to modules or `'use strict'`. - **Confusing `freeze` with `seal`.** `Object.seal()` only fixes the set of keys, the values of existing properties can still be changed. - **Thinking the method returns a copy.** It returns **the same** object, so every old reference becomes frozen too. - **Freezing an object you will need to update.** For application state it is better to build a new object (`{ ...state, city: 'Lviv' }`) than to try to mutate a frozen one. - **Forgetting about circular references in `deepFreeze()`.** Without the `Object.isFrozen()` check the recursion loops forever and blows the stack.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.