The Object isSealed() method
By Flavio Copes
Learn how the JavaScript Object.isSealed() method tells you whether an object is sealed, returning true for any object you passed through Object.seal().
Object.isSealed() accepts an object as argument, and returns true if the object is sealed, false otherwise. Objects are sealed when they are return values of the Object.seal() function.
A sealed object has a fixed shape. You can’t add new properties and you can’t remove existing ones. You can still change the values of the properties it already has.
Example:
const dog = {}
dog.breed = 'Siberian Husky'
const myDog = Object.seal(dog)
Object.isSealed(dog) //true
Object.isSealed(myDog) //true
dog === myDog //true
In the example, both dog and myDog are sealed. The argument passed as argument to Object.seal() is mutated, and can’t be un-sealed. It’s also returned as argument, hence dog === myDog (it’s the same exact object).
Sealed is not frozen
This is the part that trips people up. Sealing locks the shape of the object, not its values:
const car = Object.seal({ color: 'blue' })
car.color = 'red' //works, values are still writable
console.log(car.color) //'red'
car.year = 2019 //fails, can't add properties
delete car.color //fails, can't remove properties
console.log(car) //{ color: 'red' }
In non-strict mode the failed operations do nothing, silently. In strict mode they throw a TypeError.
If you also want the values locked, you need Object.freeze() instead.
How do the two checks relate?
Freezing is a stricter version of sealing, and the check methods reflect that.
Every frozen object is also sealed, but a sealed object is not frozen:
const frozen = Object.freeze({ breed: 'Siberian Husky' })
Object.isSealed(frozen) //true
const sealed = Object.seal({ breed: 'Siberian Husky' })
Object.isFrozen(sealed) //false
So Object.isSealed() answers “can the shape change?”, while Object.isFrozen() answers “can anything change?”.
When would you check this?
The typical case is an object you didn’t create yourself. Maybe it came from a library, or from another part of the codebase.
Since a failed property addition does nothing in non-strict mode, a sealed object can be confusing to debug. You assign a new property, no error appears, and the property just isn’t there. A quick Object.isSealed() check tells you whether the shape is locked before you spend time hunting elsewhere.
A couple of edge cases
An empty object that can’t receive new properties counts as sealed, even if Object.seal() was never called on it:
Object.isSealed({}) //false
Object.isSealed(Object.preventExtensions({})) //true
With no properties to delete, being non-extensible is enough. The same object also passes Object.isFrozen().
Passing a primitive returns true as well:
Object.isSealed(37) //true
Primitives can’t gain or lose properties, so the language treats them as sealed instead of throwing.
Related posts about js: