Skip to main content

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, writable and enumerable descriptors are left unchanged.
  • To check the state: Object.isExtensible(obj) returns false.
  • The ban also covers Object.defineProperty(), which throws a TypeError.
  • Properties inherited through the prototype stay available.

Quick example

javascript
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

javascript
Object.preventExtensions(obj)
ArgumentDescription
objThe object that will not accept new properties

It returns the object itself, already non-extensible, so it is not a copy.

javascript
console.log(Object.isExtensible(user)); // false

Object.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, writable and enumerable are not touched.

An attempt to add a property through defineProperty does not stay quiet, it throws:

javascript
const obj = {}; Object.preventExtensions(obj); try { Object.defineProperty(obj, 'x', { value: 1 }); } catch (err) { console.log('Error:', err.message); }

It prints:

javascript
Error: Cannot define property x, object is not extensible

A 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()

MethodCan addCan deleteCan changeThe configurable descriptors
preventExtensions()NoYesYesUnchanged
seal()NoNoYesAll configurable: false
freeze()NoNoNoAll 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

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

preventExtensions() 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:

BehaviourAllowed?
Adding new propertiesNo
Deleting existing onesYes
Changing valuesYes
Changing descriptorsYes
CheckObject.isExtensible(obj)

Common mistakes

  • Expecting the object to become immutable. preventExtensions() blocks neither writes nor delete; for that you need seal() or freeze().
  • Expecting an exception from a plain assignment. obj.x = 1 fails silently in sloppy mode; you only see the error under 'use strict' or from Object.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 ready
Premium

A concise answer to help you respond confidently on this topic during an interview.