Encapsulation vs. Efficiency in JavaScript

I’m an encapsulation fanatic.  I love to write code where data is protected from view and unavailable for mischief.  I like the ability to react to changes to the internal state of a function. Also, the thought of something accessing and re-writing a method or variable on another class instance scares me, and I’d rather just not let it happen.  A ton of my code ends up looking like this:

var Cookie = function() {
   var chips = {};
   this.addChip = function(type) {
      chips[type]++;
      bakeCookie();
   }
}

On the other hand, there are quite a few times when I’m writing JavaScript that I wonder when I should be worrying about efficiency.  It’s an obvious fact that using prototype methods can increase efficiency by reducing the amount of memory and processing required.  I’ve always assumed (from doing very short, non-scientific tests in a browser) that this technique pays off only when using many instances of a particular object.

var Cookie = function() {
   this.chips = {};
}
Cookie.prototype.addChip = function(type) {
   this.chips[type]++;
}

You might as well not even have the addChip method at this point. Anybody could come along and change chips - hell, they could turn it into a number or something.

Without the ability to maintain privacy, you won’t ever know when your properties change (in case you want to do something when one changes). Without privacy, you can’t hide your implementation details and provide a clean interface (in case you need to re-write the guts of your function) without a guarantee that nobody has latched onto one of the properties or methods you don’t care about anymore.

This is one of the most frustrating things about JavaScript for me. For performance, we are forced to make a decision wherein we must sacrifice privacy. Personally, I don’t use prototype methods all that much - until I know that a class I’m using will be instantiated many, many times, it just doesn’t make sense to me to lose all the benefits of privacy. Performance be damned - hell, from what I heard, you are supposed to optimize as a last resort, anyway.

I’d love to hear what other people think, though.

Comments

  1. joseanpg
    September 28th, 2008 | 11:15 am

    var Cookie = function() {
    var chips = {};
    this.addChip = function(type) {
    chips[type]++;
    }
    }

    var c = new Cookie();
    c.addChip(’menta’);
    /*
    search addChip in c : success
    search chips in [[scope]][1]: fails
    search chips in [[scope]][0]: success

    */

    //————————————————-

    var Cookie = function() {
    this.chips = {};
    }
    Cookie.prototype.addChip = function(type) {
    this.chips[type]++;
    }

    var c = new Cookie();
    c.addChip(’menta’);
    /*
    search addChip in c : fails
    search addChip in c.[[prototype]] : success
    search chips in this: success

    */

    En velocidad los dos métodos empatan.

Leave a reply