Object.isFrozen()

Determines whether an object is frozen — non-extensible with no configurable or writable properties.

Signature
Object.isFrozen(obj)
  • Added in JavaScript ES5 (2009)

Parameters

ParameterTypeDescription
$objObjectThe object to check. Non-object arguments are treated as already frozen.

Return value

booleantrue if the given object is frozen, otherwise false.

Changelog

  • PHP ES2015Passing a non-object returns true instead of throwing a TypeError, because primitives are immutable by definition.

Object.isFrozen() reports whether an object satisfies the frozen condition, which is a state test, not a record of whether Object.freeze() was ever called. An object counts as frozen when all three hold: it is not extensible, every own property is non-configurable, and every own data property is non-writable. Accessor properties impose no writability requirement, since they have no [[Writable]] attribute.

When to reach for it

Use it as a guard before mutating an object you did not create, so you can copy instead of writing, and in tests that assert a module really did export immutable data.

What trips people up

An empty object becomes frozen the moment you make it non-extensible — Object.isFrozen(Object.preventExtensions({})) is true, because there are no properties left to violate the rule. Add one writable property first and the same call returns false.

It is also shallow, matching Object.freeze(): a frozen object holding a mutable nested object still reports true. And since ES2015, primitives return true rather than throwing, so a defensive isFrozen(x) check quietly passes for numbers and strings.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Guard a mutation path: copy the object instead of writing to it when it is frozen
  • Assert in tests that an exported constants object is genuinely immutable
  • Decide whether a caller-supplied options object can be patched in place
  • Debug why an assignment silently had no effect

Frequently asked questions

Why does Object.isFrozen() return true for an object I never froze?

Because it tests state, not history: any non-extensible object whose own properties are all non-configurable and non-writable qualifies — including an empty object passed through Object.preventExtensions() or Object.seal().

Does Object.isFrozen() check nested objects?

No — the check is shallow, so an object with frozen own properties reports true even when the objects those properties point to are fully mutable.

What does Object.isFrozen() return for a number or a string?

true, since ES2015 — primitives are immutable by definition, so they are reported as frozen rather than throwing a TypeError as they did in ES5.

More examples

Every integrity level compared

Only the frozen object reports true for isFrozen; sealing stops at non-configurable and leaves values writable.

Example · javascript
const open = { a: 1 };
const prevented = Object.preventExtensions({ a: 1 });
const sealed = Object.seal({ a: 1 });
const frozen = Object.freeze({ a: 1 });

for (const [label, o] of Object.entries({ open, prevented, sealed, frozen })) {
  console.log(label, Object.isExtensible(o), Object.isSealed(o), Object.isFrozen(o));
}

Shallow, like freeze itself

The outer object reports frozen while its nested object is untouched and still mutable — isFrozen never inspects deeper than one level.

Example · javascript
const outer = Object.freeze({ inner: { n: 1 } });

console.log(Object.isFrozen(outer));
console.log(Object.isFrozen(outer.inner));

outer.inner.n = 2;
console.log(outer.inner.n);

A defensive write helper

The frozen input gets a new patched object while the original keeps mode "read"; the mutable input is patched in place and the same reference comes back.

Example · javascript
function withPatch(target, patch) {
  return Object.isFrozen(target)
    ? Object.assign({}, target, patch)
    : Object.assign(target, patch);
}

const locked = Object.freeze({ mode: "read" });
const open = { mode: "read" };

console.log(withPatch(locked, { mode: "write" }), locked.mode);
console.log(withPatch(open, { mode: "write" }) === open);

Discussion

  • Be the first to comment on this lesson.