Object.seal() Method

The holiday weekend continues and I have a little bit more time to write about some object methods. Tomorrow night I'm playing my first show in over a year, with my old band, Ruby Fray. It'll be at Hotel Vegas and I'm pretty nervous, not going to lie. It also reminds me that at some point I want to build a portion of this site out to catalog my musical endeavors -- shows I've played or will play, albums I've recorded on, gear I use, etc. But for now let's look at Object.seal(), which at first glance looks similar to Object.freeze().

When you run the Object.seal() method on an object, it means that properties may no longer be added or removed, and existing properties cannot be reconfigured, although they can have their values changed.

What does that mean and how is it different from Object.freeze()? If Object.freeze() is like a thin lacquer coating that holds everything on the surface in place, then Object.seal() is sort of like a row of books held up on a shelf with fixed bookends at either end. You can't add or remove any books from the shelf, and while you can change one book out for another, you can't swap a book for a deck of cards, or anything else that it wasn't already configured as to begin with (I'm really stretching for this analogy).

Once again let's start by looking at standard JavaScript object behavior:

const person = {
  name: 'Joey Reyes',
  age: 31,
  twitter: '@codeandtacos',
  hungry: true,
  activities: {
    coding: ['javascript', 'react', 'css'],
    cooking: true,
    cello: true
  },
};

console.log(person.hungry);
// expected result: true

console.log(person.activities.coding[1]);
// expexted result: 'react'

person.hungry = false;
console.log(person.hungry);
// expected result: false

person.city = 'Austin';
console.log(person.city);
// expected result: 'Austin'

delete person.city;
console.log(person.city);
// expected result: undefined

person.activities.coding[2] = 'html';
console.log(person.activities.coding[2]);
// expected result: 'html'

As always, object properties can be modified, added, and deleted. But let's look at how Object.seal() affects this.

const person = {
  name: 'Joey Reyes',
  age: 31,
  twitter: '@codeandtacos',
  hungry: true,
  activities: {
    coding: ['javascript', 'react', 'css'],
    cooking: true,
    cello: true
  },
};

Object.seal(person);

person.hungry = false;
console.log(person.hungry);
// expected result: false;

person.city = 'Austin';
console.log(person.city);
// expected result: undefined;

delete person.twitter;
console.log(person.twitter);
// expected result: '@codeandtacos';

person.activities.coding[2] = 'html';
console.log(person.activities.coding[2]);
// expected result: 'html';

Object.defineProperty(person, 'age', {
  value: 44
});
console.log(person.age);
// expected result: 44;

Object.defineProperty(person, 'hello', {
  get: function() {
    return 'hi there';
  }
});
console.log(person.hello);
// expected error: TypeError: Cannot define property hello, object is not extensible;

And, similar to Object.freeze(), the above failures happen silently if we are in non-strict mode, whereas in strict mode they will throw TypeErrors:

const person = {
  name: 'Joey Reyes',
  age: 31,
  twitter: '@codeandtacos',
  hungry: true,
  activities: {
    coding: ['jaascript', 'react', 'css'],
    cooking: true,
    cello: true
  },
};

Object.seal(person);

function seal() {
  "use strict"
  delete person.twitter;
  // expected error: TypeError: Cannot delete property 'twitter' of #<Object>
};

seal();

From MDN: The Object.seal() method seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable.

See more examples and further documentation here.