Javascript object initialization

I was about to write this post since a long time ago, when I was talking with two of my friends at work. I was reading some Javascript code that they were writing and I’ve noticed they were writing “classes” like this:

function User(name) {
  return {
    greeting: function() {
      return 'Hello, ' + name + '!';
    }
  }
}

User('Ford Prefect').greeting();

Objects in Javascript are basically a map (aka hash) of keys to values. A key that maps to a function can be considered a method, and a key that maps to a primitive type is what we call a public attribute (aka instance variable). This implementation works exactly like that, when we call User it will return a map with a key (greeting) that points to a function. In this case name isn’t an attribute and greeting can access its value because in Javascript the inner functions get access to all outer variables and arguments, that’s what’s called a closure.

While I understand that this is valid Javascript and it works, I knew you can also write it like this:

function User(name) {
  this.name = name;
}

User.prototype.greeting = function() {
  return 'Hello, ' + this.name + '!';
}

new User('Ford Prefect').greeting();

The ones that are more seasoned to traditional object oriented languages (e.g. Java, Python, Ruby) will recognize that the first function works like an object constructor, it receives a name parameter and stores it in an instance variable. This “class” also has a “method” in its prototype that uses that instance variable to build the user’s greeting.

This implementation has some differences in comparison with the first one:

  • name is a public attribute, it can be read and changed by any code external to that object;
  • greeting is added to the User’s prototype;
  • we’re using new to initialize the object before calling greeting;
  • any method that we add to User’s prototype will be available to any existing or future instance of User;
  • the object initialization is faster and the object consumes less memory when you create lots of instances of that class.

Regarding the memory consumption bit I’ve decided to run a quick experiment to prove it. You can find the two implementations here that you’ll run with the node.js runtime and below is a graph that compares the memory consumption outputs.

Javascript memory consumption using different object instantiation

With that in mind I’d strongly suggest to use the patterns that Crockford shows in his text Private Members in JavaScript, following that you’ll get the benefits of prototype when dealing with public stuff and you can mix it with closures to make some values private in your implementation.