In this post, I explore various object oriented JavaScript design patterns. An intermediate level of JavaScript knowledge is required to get value from this post. Before we get started exploring the various patterns below, it’s worth reviewing a couple key things about JavaScript objects.

The new Keyword in JavaScript

When the new keyword is placed in front of a function call, four things happen:

  1. A new object gets created by the constructor function.
  2. The new object gets linked to a different object.
  3. The new object gets bound as the this keyword within the constructor function call.
  4. If the constructor function does not return a value, JavaScript implicitly inserts return this; at the end of the constructor function’s execution.

Prototypal Inheritance in JavaScript

In JavaScript, the term “inheritance” in the form of prototypes is a misnomer. Prototyal Inheritance in JavaScript is much different than inheritance in traditional class-based languages, where a subclasses inherit from superclasses. I find it easiest to understand inheritance in JavaScript by abstracting the concept to human beings…

When your parents had you, you inherited their DNA — you received a copy of it. When they broke their leg, yours did not break. JavaScript is the opposite of this. In JavaScript, when your parents break their leg, yours breaks too. A term better suited than prototypal inheritance to JavaScript is prototypal delegation. When a new object is created from another object in JavaScript, it links back to the parent object’s prototype properties and methods as opposed to copying them.

The following screenshots provide further clarification about how JavaScript manages inheritance differently than class-based languages.

Screenshot of class inheritance flow from Frontend Master's Advanced JavaScript Course
Class Inheritance
Screenshot of prototypal inheritance flow in JavaScript from Frontend Master's Advanced JavaScript Course
Prototypal Inheritance

Screenshots taken from Kyle Simpson’s Advanced JavaScript course on Frontend Masters


Factory Pattern

// --------------------------
// JavaScript Factory Pattern
// --------------------------

// factory function to create car objects
function createCar(make, model, year) {
    var o = new Object();

    o.make   = make;
    o.model  = model;
    o.year   = year;
    o.sayCar = function() {
        alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');
    };

    return o;
}

// create 2 car objects for John and Jane
var johnCar = createCar('Ford', 'F150', '2011'),
    janeCar = createCar('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s Factory Pattern employs a factory function to create new objects. It was conceived as a DRY means to abstract the process of creating objects. However, there are couple problems with it:

  1. Efficiency — Methods created on the factory function are copied to all new object instances. This is inefficient.
  2. Type Determination — Because the factory function returns a new object, it makes type determination of object instances difficult. New object instances are typed as “Object”, with no indication of the instances’ context.

The type determination problem led to the creation of the Constructor Pattern.


Constructor Pattern

// ------------------------------
// JavaScript Constructor Pattern
// ------------------------------

// constructor function to create car objects
function Car(make, model, year) {
    this.make   = make;
    this.model  = model;
    this.year   = year;
    this.sayCar = function() {
        alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');
    };
}

// create 2 car objects for John and Jane
var johnCar = new Car('Ford', 'F150', '2011'),
    janeCar = new Car('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s Constructor Pattern solves the Factory Pattern’s type determination problem by replacing the factory function with a constructor function to create new objects.

In the Factory Pattern:

alert(johnCar.constructor === Car); // false
alert(johnCar.constructor === Car); // false

In the Constructor Pattern:

alert(johnCar.constructor === Car); // true
alert(johnCar.constructor === Car); // true

By convention, constructor functions always start with a capital letter, as opposed to the camelCase convention we see throughout JavaScript. This convention helps to distinguish constructor functions from other functions in JavaScript. Constructor functions must be preceded by the new keyword in JavaScript (this is what makes them a “constructor”). As stated above, the new keyword performs several actions when placed before a constructor function, shown in the example code above.

The main problem with the Constructor Pattern is, as in the Factory Pattern, inefficiency. In the Constructor Pattern, methods are [still] copied to all new object instances. This problem led to the creation of the Combination Constructor/Prototype Pattern.


Combination Constructor/Prototype Pattern

// -----------------------------------------
// Combination Constructor/Prototype Pattern
// -----------------------------------------

// constructor function to create car objects
function Car(make, model, year) {
    this.make   = make;
    this.model  = model;
    this.year   = year;
}

// constructor prototype to share properties and methods
Car.prototype.sayCar = function() {
    alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');    
};

// create 2 car objects for John and Jane
var johnCar = new Car('Ford', 'F150', '2011'),
    janeCar = new Car('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s Combination Constructor/Prototype Pattern solves the efficiency issues present in the Factory Pattern and Constructor Pattern by utilizing prototypal inheritance — or prototypal delegation as explained above. It is among the most popular object oriented design patterns in JavaScript because it allows for unique (non-shared) instance properties to be created within a constructor function, as well as shared properties and methods on the constructor function’s prototype.

One important thing to note about prototypes is that if you assign your constructor’s prototype to an object literal instead of using the dot notation, you will overwrite the default constructor property. The object literal tells JavaScript to replace the prototype with a new object, rather than augment the existing prototype. Because constructor is simply a default property on all prototypes, it gets removed when you replace the prototype with a new object. If you wish to assign a new object to a prototype and maintain the constructor relationship, you will need to recreate the constructor property and assign it the proper value — see the examples below.

Create prototype using object literal without an explicit constructor

function Car(make, model, year) {
    this.make   = make;
    this.model  = model;
    this.year   = year;
}

// create constructor prototype with object literal
Car.prototype = {
    sayCar: function() {
        alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');
    }
};

var johnCar = new Car('Ford', 'F150', '2011');

// get constructor on John's car
alert(johnCar.constructor === Car); // false
alert(johnCar.constructor === Object); // true

Create prototype using object literal and create an explicit constructor

function Car(make, model, year) {
    this.make   = make;
    this.model  = model;
    this.year   = year;
}

// create constructor prototype with object literal
Car.prototype = {
    constructor: Car,
    sayCar: function() {
        alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');
    }
};

var johnCar = new Car('Ford', 'F150', '2011');

// get constructor on John's car
alert(johnCar.constructor === Car); // true
alert(johnCar.constructor === Object); // false

The obvious reason to use the object literal syntax is to make your code simpler — to cut down on the repetition necessitated by using the dot notation for adding properties and methods to a prototype. However, the reality is that assigning a new object to a prototype makes your code more complicated because you lose the ability to determine type. Let me explain…

All properties in JavaScript have four default attributes assigned to them. These attributes are not directly accessible in JavaScript, but they have a significant impact on how the language operates. The four attributes assigned to each property in JavaScript are:

[[Configurable]]
The configurable attribute determines whether a property’s subsequent attributes may be modified, or if the property may be removed via the delete keyword. Its default value is true for all properties defined directly on an object.
[[Enumerable]]
The enumerable attribute determines if a property will be returned in for-in loop. Its default value is true for all properties defined directly on an object.
[[Writable]]
The writable attribute determines if a property is writable. Its default value is also true for all properties defined directly on an object.
[[Value]]
The value attribute contains the actual data value for a property. Its default value is undefined.

The native constructor property that exists on the constructor function’s proptotype has an [[Enumberable]] value of false. Therefore, you should ensure that when assigning a new object to your constructor function’s prototype, you also define the enumerable value on your custom-created constructor property as false. While you can do this with JavaScript’s Object.defineProperty method, it adds confusion and works against original goal of simplifying code by assigning a new object to a prototype. My advice is to stick with the dot notation — to augment the default prototype object on a constructor function, rather than replacing it with a new object literal.

Finally, the main complaint with the Combined Constructor/Prototype Pattern is that some developers perceive the separation of the constructor function and its prototype confusing. This problem led to the creation of the Dynamic Prototype Pattern.


Dynamic Prototype Pattern

// -------------------------
// Dynamic Prototype Pattern
// -------------------------

// constructor function to create car objects
function Car(make, model, year) {
    this.make   = make;
    this.model  = model;
    this.year   = year;

    // constructor prototype to share properties and methods
    if ( typeof this.sayCar !== "function" ) {
        Car.prototype.sayCar = function() {
            alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');    
        }        
    }
}


// create 2 car objects for John and Jane
var johnCar = new Car('Ford', 'F150', '2011'),
    janeCar = new Car('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s Dynamic Prototype Pattern encapsulates all information within a constructor, and has the benefits of both unique instance properties and shared prototypal properties and methods. In the Dynamic Prototype Pattern, the prototype is initialized inside of a constructor function. Then, conditional logic is implemented to ensure the prototype is initialized only on the first object instance created by a constructor.

In the example above, we check if the Car prototype has been initialized by comparing the type of the sayCar method to a function. When the johnCar instance is created, the if statement evaluates to true and the prototype method sayCar is initialized. When the janeCar instance is created, the if statement evaluates to false because the sayCar method was already initialized.

The if statement can used to test any of the properties or methods on a constructor function’s prototype. In the example above, we use the sayCar method because that is the only method that exists on the Car constructor’s prototype.


OLOO Pattern

// ------------
// OLOO Pattern
// ------------

// constructor object to create car objects
var Car = {
    init: function(make, model, year) {
        this.make   = make;
        this.model  = model;
        this.year   = year;        
    },
    sayCar: function() {
        alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');    
    }
};


// create 2 car objects for John and Jane
var johnCar = Object.create(Car),
    janeCar = Object.create(Car);

// call init method on John and Jane
johnCar.init('Ford', 'F150', '2011');
janeCar.init('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s OLOO pattern is a relatively recent object oriented JavaScript design pattern created by Kyle Simpson. OLOO stands for Objects Linked to Other Objects. The OLOO pattern simplifies the predominant class-based design patterns (listed above and below) by creating objects directly from other objects, instead of using constructor functions.

[In the OLOO Pattern] there are just pure objects that delegate to one another.

Kyle Simpson, Advanced JavaScript on Frontend Masters (OLOO video: 5:10:08–5:16:22).

In the example above, the johnCar and janeCar objects delegate to the Car object. It’s important to note that in OLOO there are no constructors. While the first letter of the Car object is still capitalized, it is done so only to remain consistent with the accepted convention.

In OLOO, rather than the implicit initialization that occurs in constructor patterns, we have explicit initialization using a method (init in the example above). The result is that OLOO allows/forces you to create and initialize your objects at separate times, rather than bundling both object creation and initialization together.

As far as efficiency through prototypal inheritance (or “delegation“) is concerned, while it may appear absent in the OLOO Pattern, prototypal inheritance is happening. In the example above, there is just one sayCar method that is shared by the johnCar and janeCar objects — shown in the screenshot below.

Screenshot of console output from OLOO code in  Chrome developer tools' console
OLOO Delegation

Because there is no constructor in the OLOO Pattern, calling johnCar instanceof Car will throw an error. Also, calling johnCar.constructor will delegate up the prototype chain to Object.prototype.constructor and return the native method. You can test the Car object’s relationship to johnCar with Car.isPrototypeOf(johnCar), which returns true.


Parasitic Constructor Pattern

// -----------------------------
// Parasitic Constructor Pattern
// -----------------------------

// constructor function to create car objects
function Car(make, model, year) {
    var o = new Object();
    
    o.make   = make;
    o.model  = model;
    o.year   = year;
    o.sayCar = function() {
        alert('I have a ' + this.year + ' ' + this.make + ' ' + this.model + '.');
    };

    return o;
}


// create 2 car objects for John and Jane
var johnCar = new Car('Ford', 'F150', '2011'),
    janeCar = new Car('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s Parasitic Constructor Pattern is similar to the Factory Pattern in that a function is used to create and return a new object. They key difference is that a constructor function is used instead of a factory function.

In the example above, the constructor function explicitly returns the new o object. This overrides the default behavior, which in the absence of the explicit return o; statement, would implicitly return a new Car object.

The Parasitic Constructor Pattern is useful in situations where you want to abstract and encapsulate code in a safe way, as in the example below taken from Professional JavaScript for Web Developers.

function SpecialArray() {

    // create the array
    var values = new Array();

    // add the values
    values.push.apply( values, arguments);

    // assign the method
    values.toPipedString = function() {
        return this.join(' |');
    };

    // return it
    return values;

}

// create a new [special] array for colors
var colors = new SpecialArray(' red', 'blue', 'green');

alert(colors.toPipedString()); // ' red | blue | green'

In this example, a constructor called SpecialArray is created. In the constructor, a new array is created and initialized using the push() method (which has all of the constructor arguments passed in). Then a method called toPipedString() is added to the instance, which simply outputs the array values as a pipe-delimited list. The last step is to return the array as the function value. Once that is complete, the SpecialArray constructor can be called, passing in the initial values for the array, and toPipedString() can be called.

Zakas, Nicholas C. (2011-12-20). Professional JavaScript for Web Developers (Kindle Locations 6714-6717). Wiley. Kindle Edition.

It’s important to note that in the Parasitic Constructor Pattern, there is no relationship between the returned object and its constructor. Continuing with the SpecialArray example above, we see that:

alert(colors instanceof SpecialArray); // false

Bottom line, the Parasitic Constructor Pattern should not be used when other patterns suffice.


Durable Constructor Pattern

// -----------------------------
// Durable Constructor Pattern
// -----------------------------

// constructor function to create car objects
function Car(make, model, year) {
    var o = new Object();

    // private variable
    var condition = 'used';

    // public method
    o.sayCar = function() {
        alert('I have a ' + condition + ' ' + year + ' ' + make + ' ' + model + '.');
    };

    return o;
}


// create 2 car objects for John and Jane
var johnCar = Car('Ford', 'F150', '2011'),
    janeCar = Car('Audi', 'A4', '2007');

// call method on Jane's car
janeCar.sayCar();

JavaScript’s Durable Constructor Pattern is similar to the Factory Pattern and Parasitic Constructor Pattern in that it creates and explicitly returns a new object. The two key differences in the Durable Constructor Pattern are:

  1. The this keyword is never used on constructor methods.
  2. The new keyword is never called before the constructor.

The unique aspect of the Durable Constructor Pattern is that it allows for private data that can be accessed through the process of closure. When the condition variable is created, it is bound to the function scope of the Car constructor. While the condition variable remains accessible to public methods attached to the o object within the Car constructor, it is not accessible outside of those methods — you are not be able to assign a different value to condition on the johnCar or janeCar objects. The private nature of variables in the Durable Constructor Pattern is also evident for arguments passed to the constructor function — make, model and year are all private. For this reason, the Durable Constructor Pattern is most often used in environments which require more security than other design patterns provide.

Finally, as with the Parasitic Constructor Pattern, there is no relationship between the returned object and its constructor:

alert(johnCar instanceof Car); // false

If you made it all the way through this post, you deserve a medal. Below is a link to download code examples for each pattern listed above.

Posted by: John Dugan

Comments

  • Marcus Nielsen

    Really good comparison! I was looking for the OLOO pattern and this article helped me out as well as show me more alternatives. Thank you for the effort.

  • Much appreciated Marcus!

    I am a big fan of Kyle’s OLOO pattern. I plan to write a post that goes much deeper into how OLOO simplifies things on a deeper level by getting rid of the class-based paradigm. At any rate, glad you enjoyed the post! 🙂

  • Pingback: Four Rules to Define "this" in JavaScript()

  • sam

    So, I understand that each pattern has plusses and minus, but on most small to medium sized projects, is there a pattern that should be used most of the time?

  • Unfortunately Sam, I cannot recommend a one size fits most pattern. I can tell you that in my projects I mostly see the “combination contstructor/prototype pattern”. But that is unique to my projects. If I were starting a project from scratch, I’d be inclined to use the OLOO pattern.

    The jQuery Plugin boilerplate that I wrote is a jQuerified version of the “combination constructor/prototype pattern” – jQuerified because it uses jQuery’s `extend` method. Check that out if you are interested: https://john-dugan.com/jquery-plugin-boilerplate-explained/

  • torijinsir

    It seems like there is flaw in OLOO. Check out the bottom of this page. http://stackoverflow.com/questions/29788181/kyle-simpsons-oloo-pattern-vs-prototype-design-pattern

  • Pingback: How to override a function when creating a new object in the prototypal inheritance? - Nikola Brežnjak blog()

  • Diogo Mello

    Nice post. Thanks!

  • Pingback: Object Oriented JavaScript Pattern Comparison | Javascript Advanced()

  • Pingback: Day 5 of 12h a day coding challenge – Code Support()

  • Pingback: Day 5 of 60 days coding challenge - Code Support()

  • NF

    Very helpful article. Thanks for sharing. The OLOO pattern is a very neat and clever solution. I plan to use it regularly in my code.

  • Glad it helped 🙂

  • Smilyan Pavlov

    Amazing article. I am using the OLOO pattern and was happy to see all the other patterns nicely laid out. The book “Javascript Patterns” by Stoyan Stefanov is also great, but I find that this article nicely summarises the OOP patterns in one place for easy reference! Thank you!

  • Happy it helped 🙂

    Thx for the book rec!

  • Wendy Bossons

    Excellent description and comparison. Thank you.

  • Glad it helped!

  • I just recently discovered the OLOO pattern and initially loved it because of it’s simple code and the departure of “pseudo-classes”, but my biggest caveat with it is that there is no way to create closures and therefor you don’t have the ability to create private properties or methods. Have you found any way around that?

  • Bobby Knuckles

    If you are referring to “asymmetry” that flaw comes from the OP’s misunderstanding of what happens in OLOO. It’s discussed elsewhere in that thread.

  • alireza alipour

    Thank you very much John