Protecting objects in JavaScript

[2013-08-25] dev, javascript, jslang
(Ad, please don’t block)

This blog post is a quick refresher of how objects can be protected in JavaScript. There are three levels of protection:

  1. Preventing extensions is the weakest level,
  2. sealing is stronger,
  3. freezing is strongest.

Preventing extension

makes it impossible to add properties to obj. Example:
    var obj = { foo: 'a' };
Now adding a propert fails silently in sloppy mode:
    > = 'b';
And throws an error in strict mode [1], which we switch to via an IIFE [2].
    > (function () { 'use strict'; = 'b' }());
    TypeError: Can't add property bar, object is not extensible
You can still delete properties, though.
    > delete

Checking whether an object is extensible

checks whether obj is extensible:
    > Object.isExtensible(obj)


prevents extensions and makes all properties “unconfigurable”. The latter means that the attributes [3] of properties can’t be changed, any more. Read-only properties stay read-only, enumerable properties stay enumerable, etc.

(As an aside, JavaScript does allow you to change an unconfigurable property from writable to read-only, due to historical reasons.)

The following example demonstrates that sealing makes all properties unconfigurable.

    > var obj = { foo: 'a' };

    > Object.getOwnPropertyDescriptor(obj, 'foo')  // before sealing
    { value: 'a',
      writable: true,
      enumerable: true,
      configurable: true }

    > Object.seal(obj)

    > Object.getOwnPropertyDescriptor(obj, 'foo')  // after sealing
    { value: 'a',
      writable: true,
      enumerable: true,
      configurable: false }
You can still change the property foo:
    > = 'b';
But you can’t change its attributes:
    > Object.defineProperty(obj, 'foo', { enumerable: false });
    TypeError: Cannot redefine property: foo
Additionally, obj is not extensible, any more.

Checking whether an object is sealed

checks whether obj is sealed:
    > Object.isSealed(obj)


makes all properties non-writable and seals obj. That is, obj is not extensible, all properties are read-only and there is no way to change that.
    var point = { x: 17, y: -5 };
Once again, you get silent failures in sloppy mode:
    > point.x = 2;  // no effect, point.x is read-only
    > point.x

    > point.z = 123;  // no effect, point is not extensible
    > point
    { x: 17, y: -5 }
And errors in strict mode:
    > (function () { 'use strict'; point.x = 2 }());
    TypeError: Cannot assign to read-only property 'x'

    > (function () { 'use strict'; point.z = 123 }());
    TypeError: Can't add property z, object is not extensible

Checking whether an object is frozen

checks whether obj is frozen:
    > Object.isFrozen(point)


  1. JavaScript’s strict mode: a summary
  2. JavaScript variable scoping and its pitfalls
  3. Object properties in JavaScript