The Object isFrozen() method

By

Learn how the JavaScript Object.isFrozen() method tells you whether an object is frozen, returning true for any object you passed through Object.freeze().

~~~

Object.isFrozen() accepts an object as argument, and returns true if the object is frozen, false otherwise. Objects are frozen when they are return values of the Object.freeze() function.

A frozen object is locked down completely. You can’t add new properties, you can’t remove existing ones, and you can’t change their values.

Example:

const dog = {}
dog.breed = 'Siberian Husky'
const myDog = Object.freeze(dog)
Object.isFrozen(dog) //true
Object.isFrozen(myDog) //true
dog === myDog //true

In the example, both dog and myDog are frozen. The argument passed as argument to Object.freeze() is mutated, and can’t be un-freezed. It’s also returned as argument, hence dog === myDog (it’s the same exact object).

What happens when you write to a frozen object?

It depends on the mode your code runs in.

In non-strict mode the write fails silently. The object stays the same, and you get no warning:

const dog = Object.freeze({ breed: 'Siberian Husky' })
dog.breed = 'Labrador'
console.log(dog.breed) //'Siberian Husky'

In strict mode (which includes ES modules) the same write throws a TypeError.

This silent failure is the pitfall to watch for. If a value refuses to update and no error appears, check Object.isFrozen() on the object. Someone may have frozen it upstream.

Freezing is shallow

Object.freeze() only freezes the object itself, not the objects nested inside it. Object.isFrozen() reflects that:

const config = Object.freeze({
  server: { port: 3000 }
})

config.server.port = 8080
console.log(config.server.port) //8080

Object.isFrozen(config) //true
Object.isFrozen(config.server) //false

The config object is frozen, but config.server is a separate object that never went through Object.freeze(). Its properties are still writable.

A couple of edge cases

An empty object that can’t receive new properties counts as frozen, even without calling Object.freeze():

Object.isFrozen({}) //false
Object.isFrozen(Object.preventExtensions({})) //true

There are no properties to change or remove, so being non-extensible is enough to qualify.

Passing a primitive returns true too:

Object.isFrozen(37) //true

Primitives can’t be modified, so the language treats them as frozen instead of throwing.

~~~

Related posts about js: