The Factory Pattern in JavaScript

We could also call this article, “JavaScript Constructors Considered Harmful.”

I recall reading a post recently which describes factory methods as a best practice. I can’t tell you how thrilled this made me as I’ve been advocating this for years, even to the extreme view that the author used as an example: new Form().

In my most recent talk at AJAXWorld 2009, I briefly discussed the Factory Pattern as it applies to JavaScript. In my talk, I took a jump away from simple best practices and gave a real-world problem/solution approach to factories in JavaScript.

The problem: JavaScript will allow you to invoke constructor functions as normal functions.
The simplest possible solution: Use a factory method to instantiate everything.

My personal recommendation is to only use constructors internally and to never expose constructors directly.

What the hell? Why are constructors so bad?

Constructors in JavaScript are bad because of one thing, and it’s the same thing that is at the heart of almost all of JavaScript’s problems: implied global scope.

Consider the following code:

// Define our constructor function
var Person = function (name, location) {
    this.name = name;
    this.location = location;
};

// Create one instance of Person
var mike = new Person('Mike G.', 'NYC');

// Create another instance of Person
var alex = Person('Alex H.', 'NYC');

Did you spot my mistake? I omitted the new keyword while creating the second Person instance. If you run this code in any web browser, you’ll notice that the browser will redirect you immediately upon running it.

This is a big problem.

When you invoke any function with the new keyword, it treats it as a constructor and executes within the context of the newly created instance. When you invoke any function without the new keyword, it treats it as a normal function and executes within the context in which the function was defined (typically window).

With that knowledge, go back and re-read the code and tell me why the browser redirects now…

Factories save the day

The easiest way to fix this problem is to use a factory. Here’s my proposed solution:

var Person = function (name, location) {
    return Person.factory(name, location);
};

Person.factory = function (name, location) {
    return new Person(name, factory);
};

One of JavaScript’s brilliant features is that Constructors can have return values. In this example, my constructor is returning the result of the Person.factory call.

Now it doesn’t matter how you invoke this constructor. You can use new or you can omit it. This is defensive code and it’s JavaScript done right.

Posted on June 26th, 2009 in Code, Design Patterns, JavaScript | No Comments »

« Previous

From the Archive

Synchronous Execution in JavaScript

Complex front-end web applications generally consist of many components which are initialized and configured at load time. What I’ve come to find out quite recently is that some browsers simply can’t handle too many things going on at once (eg: IE6 and lots of DOM operations).
As a small experiment, I decided to write a [...]

May 27th, 2009. Continue »

Upcoming Talk: Object Oriented JavaScript

I will be presenting Object Oriented JavaScript at AjaxWorld this year.
You can find the talk’s abstract below. I’m still working on the slides so if there is anything you would like me to touch on, I’m open to suggestions.
From the Sessions page:
JavaScript has taken a lot of heat over the last few years for [...]

May 6th, 2009. Continue »

Review: Learning Dojo by Peter Svensson

… or How to Write a Good JavaScript Book
It’s widely known that the vast majority of JavaScript books that exist are bad. Unfortunately, I have another one to add to the list: Learning Dojo by Peter Svensson.
I fought with myself over whether or not it is a good idea to post this review. I’m afraid [...]

February 23rd, 2009. Continue »

Site Stuff

Pages

Projects

Archives

Categories