Object.seal()
Seals an object so properties cannot be added or removed, while existing values stay writable.
Object.seal(obj)- Added in JavaScript ES5 (2009)
Parameters
| Parameter | Type | Description |
|---|---|---|
$obj | Object | The object which should be sealed. Non-object arguments are returned unchanged. |
Return value
ObjectThe same object that was passed in, now sealed.
Errors
In strict mode, later attempts to add or delete a property, or to convert a data property to an accessor, throw a TypeError; outside strict mode they fail silently.
Changelog
- PHP ES2015Passing a non-object returns that value unchanged instead of throwing a TypeError.
Object.seal() fixes an object's shape without fixing its contents. It marks the object non-extensible and every own property non-configurable, so you cannot add a property, delete one, or convert a data property into an accessor — but you can still reassign the values of existing writable properties. It mutates and returns the same object.
When to reach for it
Seal a mutable state or settings object whose field list is fixed. Typos then become visible: state.retires = 3 on a sealed object throws in strict mode instead of quietly creating a fifth field nobody reads. It is the right middle ground when Object.freeze() is too strict because the values genuinely change over time.
What trips people up
Sealing does not make anything read-only. Developers reach for it expecting immutability and are surprised that sealed.a = 99 works fine — that is Object.freeze()'s job.
Like freeze, it is shallow and it fails silently outside strict mode. And a property that was already non-writable before you sealed stays non-writable; sealing changes configurability, not writability. On arrays, sealing blocks push() and pop() but leaves index assignment working.
Example
When to use it
- Lock the field list of a mutable state object so typos throw instead of adding fields
- Hand a caller an options object whose values they may tune but whose keys they may not extend
- Fix a record's shape after initialisation while its values keep updating
- Prevent library consumers from deleting properties your code depends on
Frequently asked questions
What is the difference between Object.seal() and Object.freeze()?
Sealing locks the set of keys but leaves existing writable values changeable, while freezing also makes every data property read-only.
Can you unseal an object?
No — the integrity levels are one-way; once an object is non-extensible and its properties non-configurable, nothing can reverse it, so you must build a fresh object instead.
Does Object.seal() prevent changing property values?
No — it only prevents adding, deleting and reconfiguring properties; use Object.freeze() if you also need values to be immutable.
More examples
Seal versus freeze
The sealed object accepts the new value while the frozen one keeps "bar" — the single behavioural difference between the two levels.
const sealed = Object.seal({ foo: "bar" });
const frozen = Object.freeze({ foo: "bar" });
sealed.foo = "changed";
console.log("sealed:", sealed.foo);
try { frozen.foo = "changed"; } catch { console.log("frozen write rejected"); }
console.log("frozen:", frozen.foo);Sealed arrays
Length-changing methods fail because they add or delete index properties, but overwriting an existing element is unaffected.
const list = Object.seal([1, 2, 3]);
list[0] = 99; // element assignment still works
try { list.push(4); } catch (e) { console.log("push threw:", e.constructor.name); }
try { list.pop(); } catch (e) { console.log("pop threw:", e.constructor.name); }
console.log(list, list.length);Descriptors after sealing
Both properties become configurable: false, but writable is untouched — a stays writable and b, already read-only, remains read-only.
const obj = { a: 1 };
Object.defineProperty(obj, "b", { value: 2, writable: false, enumerable: true, configurable: true });
Object.seal(obj);
console.log(Object.getOwnPropertyDescriptor(obj, "a"));
console.log(Object.getOwnPropertyDescriptor(obj, "b"));
Discussion