Object oriented javascript with prototypes vs closures

I'm curious what the difference is between the following OOP javascript techniques. They seem to end up doing the same thing but is one considered better than the other?

function Book(title) {
    this.title = title;
}

Book.prototype.getTitle = function () {
    return this.title;
};

var myBook = new Book('War and Peace');
alert(myBook.getTitle())

vs

function Book(title) {
    var book = {
        title: title
    };
    book.getTitle = function () {
        return this.title;
    };
    return book;
}

var myBook = Book('War and Peace');
alert(myBook.getTitle())

The second one doesn't really create an instance, it simply returns an object. That means you can't take advantage of operators like instanceof. Eg. with the first case you can do if (myBook instanceof Book) to check if the variable is a type of Book, while with the second example this would fail.

If you want to specify your object methods in the constructor, this is the proper way to do it:

function Book(title) {
    this.title = title;

    this.getTitle = function () {
        return this.title;
    };
}

var myBook = new Book('War and Peace');
alert(myBook.getTitle())

While in this example the both behave the exact same way, there are differences. With closure-based implementation you can have private variables and methods (just don't expose them in the this object). So you can do something such as:

function Book(title) {
    var title_;

    this.getTitle = function() {
        return title_;
    };

    this.setTitle = function(title) {
        title_ = title;
    };

    // should use the setter in case it does something else than just assign
    this.setTitle(title);
}

Code outside of the Book function can not access the member variable directly, they have to use the accessors.

Other big difference is performance; Prototype based classing is usually much faster, due to some overhead included in using closures. You can read about the performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx


Which is better can sometimes be defined by the context of their usage.

Three constraints of how I choose between Prototype and Closure methods of coding (I actively use both):

  1. Performance/Resources
  2. Compression requirements
  3. Project Management

1. Performance/Resources

For a single instance of the object, either method is fine. Any speed advantages would most likely be negligible.

If I am instantiating 100,000 of these, like building a book library, then the Prototype Method would be preferred. All the .prototype. functions would only be created once, instead of these functions being created 100,000 times if using the Closure Method. Resources are not infinite.

2. Compression

Use the Closure Method if compression efficiency is important (ex: most browser libraries/modules). See below for explanation:

Compression - Prototype Method

function Book(title) {
    this.title = title;
}

Book.prototype.getTitle = function () {
  return this.title;
};

Is YUI compressed to

function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title};

A savings of about 18% (all spaces/tabs/returns). This method requires variables/functions to be exposed (this.variable=value) so every prototype function can access them. As such, these variables/functions can't be optimized in compression.

Compression - Closure Method

function Book(title) {
  var title = title; // use var instead of this.title to make this a local variable

this.getTitle = function () {
  return title;
};
}

Is YUI compressed to

function Book(a){var a=a;this.getTitle=function(){return a}};

A savings of about 33%. Local variables can be optimized. In a large module, with many support functions, this can have significant savings in compression.

3. Project Management

In a project with multiple developers, who could be working on the same module, I prefer the Prototype Method for that module, if not constrained by performance or compression.

For browser development, I can override the producton.prototype.aFunction from "production.js" in my own "test.js" (read in afterwords) for the purpose of testing or development, without having to modify the "production.js", which may be in active development by a different developer.

I'm not a big fan of complex GIT repository checkout/branch/merge/conflict flow. I prefer simple.

Also, the ability to redefine or "hijack" a module's function by a testbench can be beneficial, but too complicated to address here...


The former method is how JavaScript was intended to be used. The latter is the more modern technique, popularised in part by Douglas Crockford. This technique is much more flexible.

You could also do:

function Book(title) {
    return {
        getTitle: function () {
            return title;
        }
    }
}

The returned object would just have an accessor called getTitle, which would return the argument, held in closure.

Crockford has a good page on Private Members in JavaScript - definitely worth a read to see the different options.