Object.seal() locks an object's shape — no new properties can be added and none can be removed — while still allowing existing property values to change. It sits between a fully mutable object and a fully frozen one.
1Object.seal() | JavaScript Tutorial - In-Depth Guide Part 1
Object.seal() prevents adding new properties and deleting existing ones, but still allows the values of existing properties to be changed.
const user = Object.seal({ name: 'Ana' });
user.name = 'Bea'; // OK, values can change
user.age = 30; // ignored, can't add new keys
delete user.name; // ignored, can't remove keysLocking the Shape
2Object.seal() | JavaScript Tutorial - In-Depth Guide Part 2
Sealing is useful when you want to guarantee an object always has exactly the same set of fields, without restricting what those fields can hold.
const settings = Object.seal({ theme: 'light', fontSize: 14 });
settings.theme = 'dark'; // fine
settings.newFeatureFlag = true; // silently ignoredFixed-Shape Records
3Object.seal() | JavaScript Tutorial - In-Depth Guide Part 3
Object.isSealed() reports whether an object has been sealed, and every frozen object is also considered sealed (freeze is a stricter superset).
const frozen = Object.freeze({});
Object.isSealed(frozen); // true — freeze implies sealSeal vs Freeze Hierarchy
4Object.seal() | JavaScript Tutorial - In-Depth Guide Part 4
Like freeze, seal is shallow — nested objects referenced by a sealed object's properties are completely unaffected.
const obj = Object.seal({ nested: {} });
obj.nested.newProp = 'fine'; // works, nested isn't sealedShallow, Like Freeze
5Object.seal() | JavaScript Tutorial - In-Depth Guide Part 5
Choosing between seal and freeze comes down to whether you need to update values later: seal for mutable-value fixed-shape records, freeze for full immutability.
// Fixed shape, changing values:
const formState = Object.seal({ email: '', password: '' });
// Never changes:
const API_ROUTES = Object.freeze({ users: '/api/users' });Choosing Seal vs Freeze
6Step-by-Step Breakdown
Object.seal() prevents adding new properties and deleting existing ones, but still allows the values of existing properties to be changed.
Checkpoint: On a sealed object, can you change the value of an existing property?
- →Yes, only adding/removing keys is blocked
- →No, seal locks values too, just like freeze
Sealing is useful when you want to guarantee an object always has exactly the same set of fields, without restricting what those fields can hold.
Object.isSealed() reports whether an object has been sealed, and every frozen object is also considered sealed (freeze is a stricter superset).
Checkpoint: Does Object.isSealed() return true for an object that was frozen (not explicitly sealed)?
- →Yes, freeze implies sealing
- →No, freeze and seal are entirely unrelated
Like freeze, seal is shallow — nested objects referenced by a sealed object's properties are completely unaffected.
Choosing between seal and freeze comes down to whether you need to update values later: seal for mutable-value fixed-shape records, freeze for full immutability.
Next, we'll explore 'Object.assign()'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Sealing a Component's Accessibility Options Object Prevents Silent Config Drift
Sealing a fixed-shape accessibility options object (e.g. { reducedMotion, highContrast }) ensures a typo in a consuming component fails loudly or silently no-ops instead of quietly introducing an untracked, unused flag.
SEO Implications
- 1
No Direct SEO Effect
Object.seal() is a data-integrity mechanism with only indirect SEO relevance, via reducing configuration bugs in server-rendered logic.
Best Practices
Use Seal for Objects With a Known, Fixed Set of Mutable Fields
It documents and enforces that the object's schema is fixed, catching accidental typo'd property additions (like `usre.name` creating a stray new key) that would otherwise fail silently.
Frequent Bugs
A typo like `user.naem = 'x'` on a plain object silently creates a stray new property instead of raising an error, hiding the mistake.
Sealing the object turns this typo into a silent no-op that a linter or a strict-mode assertion can catch, or logs clearly if you check the return value/behavior in tests.
Assuming Object.seal() prevents value changes the same way freeze does, then being confused when a supposedly 'locked' object's properties still change.
Remember seal only locks the shape (keys), not the values — use Object.freeze() instead if values must also be immutable.
Real-World Examples
Sealing a Fixed-Shape Settings Object
A settings panel needed to guarantee no code path could accidentally introduce a new, untracked settings key, while still allowing normal value updates as the user changed preferences.
const settings = Object.seal({
theme: 'light',
notifications: true,
});
settings.theme = 'dark'; // allowed
settings.experimental = true; // silently ignored