Object.preventExtensions() in JavaScript
Object.preventExtensions() is a built-in JavaScript method that forbids adding new properties to an object while still allowing you to change and delete the existing ones. It is the softest form of object protection, unlike seal() and freeze().
Theory
TL;DR
Object.preventExtensions(obj)forbids adding new properties.- Existing properties can be changed and can be deleted.
- The
configurable,writableandenumerabledescriptors are left unchanged. - To check the state:
Object.isExtensible(obj)returnsfalse. - The ban also covers
Object.defineProperty(), which throws aTypeError. - Properties inherited through the prototype stay available.
Quick example
const user = {
name: 'Alice',
age: 25
};
Object.preventExtensions(user);
user.city = 'Kyiv'; // will not be added
delete user.age; // can be deleted
user.name = 'Oleh'; // can be changed
console.log(user); // { name: 'Oleh' }After Object.preventExtensions():
- new properties cannot be added;
- old ones can be deleted;
- existing values can be changed.
Syntax and checking the state
Object.preventExtensions(obj)| Argument | Description |
|---|---|
obj | The object that will not accept new properties |
It returns the object itself, already non-extensible, so it is not a copy.
console.log(Object.isExtensible(user)); // falseObject.isExtensible(obj) returns false when new properties cannot be added to the object. The operation is irreversible: an object can never be made extensible again.
What happens under the hood
Object.preventExtensions(obj) does the following:
- forbids adding new properties, including through
Object.defineProperty(); - existing properties stay writable and deletable;
configurable,writableandenumerableare not touched.
An attempt to add a property through defineProperty does not stay quiet, it throws:
const obj = {};
Object.preventExtensions(obj);
try {
Object.defineProperty(obj, 'x', { value: 1 });
} catch (err) {
console.log('Error:', err.message);
}It prints:
Error: Cannot define property x, object is not extensibleA plain assignment obj.x = 1 behaves differently: in sloppy mode it silently does nothing, while under 'use strict' it throws a TypeError as well.
Differences from seal() and freeze()
| Method | Can add | Can delete | Can change | The configurable descriptors |
|---|---|---|---|---|
preventExtensions() | No | Yes | Yes | Unchanged |
seal() | No | No | Yes | All configurable: false |
freeze() | No | No | No | All configurable: false, writable: false |
So preventExtensions() is the softest protection option. It simply "closes the door" but does not get in the way of working with what is already there.
Prototypes and inherited properties
const parent = { role: 'user' };
const child = Object.create(parent);
Object.preventExtensions(child);
child.name = 'Alice'; // will not be added
console.log(child.name); // undefined
console.log(child.role); // "user", inherited from the prototypepreventExtensions() does not affect inherited properties, they stay reachable through the prototype. Only the set of the object's own properties is restricted; the prototype itself, unless you protect it separately, can still be extended, and the new fields become visible to child immediately.
Summary table:
| Behaviour | Allowed? |
|---|---|
| Adding new properties | No |
| Deleting existing ones | Yes |
| Changing values | Yes |
| Changing descriptors | Yes |
| Check | Object.isExtensible(obj) |
Common mistakes
- Expecting the object to become immutable.
preventExtensions()blocks neither writes nordelete; for that you needseal()orfreeze(). - Expecting an exception from a plain assignment.
obj.x = 1fails silently in sloppy mode; you only see the error under'use strict'or fromObject.defineProperty(). - Hoping to roll the protection back. An object cannot be made extensible again, the state is irreversible.
- Forgetting about the prototype. Only own properties are protected; adding fields to the prototype still affects the object.
- Treating the effect as deep. Nested objects remain fully extensible and have to be handled separately.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.