piotrwalat.net

Preventing modification of JavaScript objects

6 comments

Due to its dynamic nature, JavaScript makes it extremely easy to modify objects that you do not own. It also means that anyone can easily modify objects that you have written. This is seemingly a very powerful feature and many developers may be tempted to use it in order to extend or modify behavior of objects (even DOM methods such as document.getElementById() can be overwritten). Such practice should generally be avoided as it can lead to maintenance problems and can produce hard to find bugs. ECMAScript 5 introduced a bunch of methods that allow programmers to restrict modification of objects. This new language feature can be very helpful when writing libraries or when writing code in bigger teams.

If you don’t own it, don’t modify it

A good JavaScript rule says that you shouldn’t modify objects you don’t own. For example if you decide to override a method chances are that you are breaking libraries that depend on it and you are generating a lot of confusion among other developers.

Here we modify windows.alert to log all string values to console instead displaying a message box. For other types we invoke the original function. Regardless of our motivation, the result will be a lot of confusion among developers using alert function. Of course playing with DOM objects and methods like getElementById() can lead to far severe consequences (nasty, nasty bugs).

Modifying objects by adding new methods can also be harmful.

The biggest problem with this approach are naming collisions that may happen in the future. Even if Math object does not contain cube method now, next iteration of JavaScript standard may introduce it (even though this is unlikely). It will mean that we replace native (that is possible faster, better or simply behaving differently) implementation without even knowing this. This may painful and costly maintenance problems in your applications. A real world example of this problem is document.getElementsByClassName() introduced by Prototype library, just to be later included as a part of the standard.

Unfortunately there is no guarantee that other developers will leave your objects alone. If you provide something that in your opinion should be closed to modifications, you can use new JavaScript feature described below.

 Object.preventExtensions()

You can use Object.preventExtensions() to prevent new methods or properties being added to the object. Please note that existing members can be modified or even deleted. To determine whether an object is extensible or not use Object.isExtensible() method.

In this example if you try to add new members to a locked down object the operation will silently fail. This behavior will be changed if we use strict mode.

In strict mode an error will be thrown when we try to add new member.

Object.seal()

Use Object.seal() to seal an object. Every sealed object is non-extensible (so it acts as if we acted with Object.preventExtension() on it ), but additionally none of its existing properties or methods can be removed.

Again, in strict mode silent failures will be replaced by errors.

Object.freeze()

Frozen objects are considered to be sealed (and non-extensible as well). The additional constraint is that no modifications to existing properties or methods can occur.

In strict mode instead of silent failures we would see errors.

This methods should be supported by any recent version of all major browsers:

  •  IE 9+ (this means it should work in WinJS, but haven’t tested it),
  •  Firefox 4+
  •  Safari 5.1+
  •  Chrome 7+
  •  Opera 12+

 

Written by Piotr Walat

September 13th, 2012 at 2:00 am

  • Ben

    Small note: It’s Object.preventExtensions(foo); not Object.preventEntension(foo) … notice the s.

    The code was okay I think, but your title is off.

    • http://www.piotrwalat.net/ Piotr Walat

      Hi Ben, many thanks for catching this typo, yeah the title missed ‘s’. Code is ok.

  • TiTi

    Thx, I’m definitively going to use thoses methods, especially Object.freeze() !

  • Chris

    Nice tips, plus you like Opeth.  Good in my book.

    • http://www.piotrwalat.net/ Piotr Walat

      heheh, yeah I do

  • Pingback: Preventing modification of JavaScript objects | Code 4 Me University