The Object seal() method

By

Learn how the JavaScript Object.seal() method locks an object so you cannot add or remove properties, while still letting you change existing ones.

~~~

The JavaScript Object.seal() method locks the structure of an object. You can’t add new properties, and you can’t remove the existing ones. You can still change the values of properties that are already there.

Pass it the object you want to seal:

const dog = {}
dog.breed = 'Siberian Husky'
Object.seal(dog)

dog.breed = 'Pug' //works, the property already exists
dog.name = 'Roger' //fails, can't add new properties
delete dog.breed //fails, can't remove properties

The object is sealed in place. The return value is the same object you passed in, not a copy:

const myDog = Object.seal(dog)
myDog === dog //true

You can check if an object is sealed with Object.isSealed():

Object.isSealed(dog) //true

Under the hood, sealing marks every existing property as non-configurable, and makes the object non-extensible. That’s why you can’t delete properties or add new ones, but writable properties stay writable.

What happens when you violate the seal?

It depends on strict mode.

In non-strict code, adding or deleting a property on a sealed object fails silently. No error, the object just doesn’t change. This can be confusing to debug, because the assignment looks like it worked.

In strict mode (and inside ES modules, which are strict by default), you get a TypeError instead:

'use strict'

const dog = { breed: 'Siberian Husky' }
Object.seal(dog)

dog.name = 'Roger' //TypeError: Cannot add property name, object is not extensible
delete dog.breed //TypeError: Cannot delete property 'breed' of #<Object>

My advice is to work in strict mode, so failures are loud and you notice them right away.

How is it different from freeze() and preventExtensions()?

JavaScript gives us three levels of locking.

Object.freeze() is the strictest. It does everything seal() does, and it also makes every property read-only. A frozen object can’t change at all.

Object.seal() sits in the middle. The shape is fixed, the values are not.

Object.preventExtensions() is the loosest. It only blocks adding new properties. You can still delete existing ones.

Watch out for nested objects

Sealing is shallow. Objects stored inside properties are not sealed:

const owner = { info: { name: 'Roger' } }
Object.seal(owner)

owner.info.name = 'Syd' //works
owner.info.age = 7 //works, info itself is not sealed

If you need the whole structure locked, call Object.seal() on each nested object too.

~~~

Related posts about js: