JavaScript Class Patterns Revisited: Endgame

Posted by Liam McLennan on Geeks with Blogs See other posts from Geeks with Blogs or by Liam McLennan
Published on Thu, 17 Feb 2011 22:01:53 GMT Indexed on 2011/02/17 23:26 UTC
Read the original article Hit count: 305

Filed under:

 

imageI recently described some of the patterns used to simulate classes (types) in JavaScript. But I missed the best pattern of them all. I described a pattern I called constructor function with a prototype that looks like this:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  toString: function() {
    return this.name + " is " + this.age + " years old.";
  }
};

var john = new Person("John Galt", 50);

console.log(john.toString());

and I mentioned that the problem with this pattern is that it does not provide any encapsulation, that is, it does not allow private variables. Jan Van Ryswyck recently posted the solution, obvious in hindsight, of wrapping the constructor function in another function, thereby allowing private variables through closure. The above example becomes:

var Person = (function() {
  // private variables go here
  var name,age;
  
  function constructor(n, a) {
    name = n;
    age = a;
  }

  constructor.prototype = {
    toString: function() {
      return name + " is " + age + " years old.";
    }
  };
  
  return constructor;  
})();

var john = new Person("John Galt", 50);
console.log(john.toString());

Now we have prototypal inheritance and encapsulation. The important thing to understand is that the constructor, and the toString function both have access to the name and age private variables because they are in an outer scope and they become part of the closure.

© Geeks with Blogs or respective owner