You are previewing Learning JavaScript Design Patterns.

Learning JavaScript Design Patterns

Cover of Learning JavaScript Design Patterns by Addy Osmani Published by O'Reilly Media, Inc.
  1. Learning JavaScript Design Patterns
  2. SPECIAL OFFER: Upgrade this ebook with O’Reilly
  3. Preface
    1. Target Audience
    2. Credits
    3. Reading
    4. Conventions Used in This Book
    5. Using Code Examples
    6. Safari® Books Online
    7. How to Contact Us
    8. Acknowledgments
  4. 1. Introduction
  5. 2. What Is a Pattern?
    1. We Already Use Patterns Every Day
  6. 3. “Pattern”-ity Testing, Proto-Patterns, and the Rule of Three
  7. 4. The Structure of a Design Pattern
  8. 5. Writing Design Patterns
  9. 6. Anti-Patterns
  10. 7. Categories of Design Patterns
    1. Creational Design Patterns
    2. Structural Design Patterns
    3. Behavioral Design Patterns
  11. 8. Design Pattern Categorization
    1. A Brief Note on Classes
  12. 9. JavaScript Design Patterns
    1. The Constructor Pattern
      1. Object Creation
      2. Basic Constructors
      3. Constructors with Prototypes
    2. The Module Pattern
      1. Object Literals
      2. The Module Pattern
      3. Module Pattern Variations
    3. The Revealing Module Pattern
      1. Advantages
      2. Disadvantages
    4. The Singleton Pattern
    5. The Observer Pattern
      1. Differences Between the Observer and Publish/Subscribe Pattern
      2. Advantages
      3. Disadvantages
      4. Publish/Subscribe Implementations
    6. The Mediator Pattern
      1. Basic Implementation
      2. Advanced Implementation
      3. Example
      4. Advantages and Disadvantages
      5. Mediator Versus Observer
      6. Mediator Versus Facade
    7. The Prototype Pattern
    8. The Command Pattern
    9. The Facade Pattern
      1. Notes on Abstraction
    10. The Factory Pattern
      1. When to Use the Factory Pattern
      2. When Not to Use the Factory Pattern
      3. Abstract Factories
    11. The Mixin Pattern
    12. Subclassing
    13. Mixins
      1. Advantages and Disadvantages
    14. The Decorator Pattern
    15. Pseudoclassical Decorators
      1. Interfaces
      2. Abstract Decorators
    16. Decorators with jQuery
    17. Advantages and Disadvantages
    18. Flyweight
      1. Using Flyweights
      2. Flyweights and Sharing Data
      3. Implementing Classical Flyweights
      4. Converting Code to Use the Flyweight Pattern
      5. A Basic Factory
      6. Managing the Extrinsic States
      7. The Flyweight Pattern and the DOM
  13. 10. JavaScript MV* Patterns
    1. MVC
      1. Smalltalk-80 MVC
    2. MVC for JavaScript Developers
      1. Models
      3. Controllers
      4. Controllers in Another Library (Spine.js) Versus Backbone.js
    3. What Does MVC Give Us?
    4. Smalltalk-80 MVC in JavaScript
      1. Delving Deeper
      2. Summary
    5. MVP
      1. Models, Views, and Presenters
      2. MVP or MVC?
      3. MVC, MVP, and Backbone.js
    6. MVVM
      1. History
      2. Model
      3. View
      4. ViewModel
      5. Recap: The View and the ViewModel
      6. Recap: The ViewModel and the Model
    7. Pros and Cons
      1. Advantages
      2. Disadvantages
    8. MVVM with Looser Data Bindings
    9. MVC Versus MVP Versus MVVM
    10. Backbone.js Versus KnockoutJS
  14. 11. Modern Modular JavaScript Design Patterns
    1. A Note on Script Loaders
    2. AMD
      1. Getting Started with Modules
      2. AMD Modules with Dojo
      3. AMD Module Design Patterns (Dojo)
      4. AMD Modules with jQuery
      5. AMD Conclusions
    3. CommonJS
      1. Getting Started
      2. Consuming Multiple Dependencies
      3. Loaders and Frameworks that Support CommonJS
      4. Is CommonJS Suitable for the Browser?
      5. Related Reading
    4. AMD and CommonJS: Competing, but Equally Valid Standards
      1. UMD: AMD and CommonJS-Compatible Modules for Plug-ins
    5. ES Harmony
      1. Modules with Imports and Exports
      2. Modules Loaded from Remote Sources
      3. Module Loader API
      4. CommonJS-like Modules for the Server
      5. Classes with Constructors, Getters, and Setters
      6. ES Harmony Conclusions
      7. Related Reading
    6. Conclusions
  15. 12. Design Patterns in jQuery
    1. The Composite Pattern
    2. The Adapter Pattern
    3. The Facade Pattern
    4. The Observer Pattern
    5. The Iterator Pattern
    6. Lazy Initialization
    7. The Proxy Pattern
    8. The Builder Pattern
  16. 13. jQuery Plug-in Design Patterns
    1. Patterns
    2. A Lightweight Start Pattern
      1. Further Reading
    3. Complete Widget Factory Pattern
      1. Further Reading
    4. Nested Namespacing Plug-in Pattern
      1. Further Reading
    5. Custom Events Plug-in Pattern (with the Widget Factory)
      1. Further Reading
    6. Prototypal Inheritance with the DOM-to-Object Bridge Pattern
      1. Further Reading
    7. jQuery UI Widget Factory Bridge Pattern
      1. Further Reading
    8. jQuery Mobile Widgets with the Widget Factory
    9. RequireJS and the jQuery UI Widget Factory
      1. Usage
      2. Further Reading
    10. Globally and Per-Call Overridable Options (Best Options Pattern)
      1. Further Reading
    11. A Highly Configurable and Mutable Plug-in Pattern
      1. Further Reading
    12. What Makes a Good Plug-in Beyond Patterns?
      1. Quality
      2. Code Style
      3. Compatibility
      4. Reliability
      5. Performance
      6. Documentation
      7. Likelihood of maintenance
    13. Conclusions
    14. Namespacing Patterns
    15. Namespacing Fundamentals
      1. Single Global Variables
      2. Prefix Namespacing
      3. Object Literal Notation
      4. Nested Namespacing
      5. Immediately Invoked Function Expressions (IIFE)s
      6. Namespace Injection
    16. Advanced Namespacing Patterns
      1. Automating Nested Namespacing
      2. Dependency Declaration Pattern
      3. Deep Object Extension
      4. Recommendation
  17. 14. Conclusions
  18. A. References
  19. Index
  20. About the Author
  21. Colophon
  22. SPECIAL OFFER: Upgrade this ebook with O’Reilly
  23. Copyright

The Constructor Pattern

In classical object-oriented programming languages, a constructor is a special method used to initialize a newly created object once memory has been allocated for it. In JavaScript, as almost everything is an object, we’re most often interested in object constructors.

Object constructors are used to create specific types of objects—both preparing the object for use and accepting arguments a constructor can use to set the values of member properties and methods when the object is first created (Figure 9-1).

Constructor pattern

Figure 9-1. Constructor pattern

Object Creation

The two common ways to create new objects in JavaScript are as follows:

// Each of the following options will create a new empty object:

var newObject = {}; 

// or which is a shorthand for the object constructor
var newObject = new Object();

Where the Object constructor creates an object wrapper for a specific value, or where no value is passed, it will create an empty object and return it.

There are then four ways in which keys and values can be assigned to an object:

// ECMAScript 3 compatible approaches

// 1. Dot syntax

// Set properties
newObject.someKey = "Hello World"; 

// Get properties
var key = newObject.someKey; 

// 2. Square bracket syntax

// Set properties
newObject["someKey"] = "Hello World"; 

// Get properties
var key = newObject["someKey"]; 

// ECMAScript 5 only compatible approaches
// For more information see:

// 3. Object.defineProperty

// Set properties 
Object.defineProperty( newObject, "someKey", {
    value: "for more control of the property's behavior",
    writable: true,
    enumerable: true,
    configurable: true

// If the above feels a little difficult to read, a short-hand could
// be written as follows:

var defineProp = function ( obj, key, value ){
  config.value = value;
  Object.defineProperty( obj, key, config );

// To use, we then create a new empty "person" object
var person = Object.create( null );

// Populate the object with properties
defineProp( person, "car",  "Delorean" );
defineProp( person, "dateOfBirth", "1981" );
defineProp( person, "hasBeard", false );

// 4. Object.defineProperties

// Set properties
Object.defineProperties( newObject, { 

  "someKey": {  
    value: "Hello World",  
    writable: true  

  "anotherKey": {  
    value: "Foo bar",  
    writable: false  


// Getting properties for 3. and 4. can be done using any of the
// options in 1. and 2.

As we will see a little later in the book, these methods can even be used for inheritance, as follows:

// Usage:

// Create a race car driver that inherits from the person object
var driver = Object.create( person );

// Set some properties for the driver
defineProp(driver, "topSpeed", "100mph");

// Get an inherited property (1981)
console.log( driver.dateOfBirth );

// Get the property we set (100mph)
console.log( driver.topSpeed );

Basic Constructors

As we saw earlier, JavaScript doesn’t support the concept of classes, but it does support special constructor functions that work with objects. By simply prefixing a call to a constructor function with the keyword new, we can tell JavaScript we would like the function to behave like a constructor and instantiate a new object with the members defined by that function.

Inside a constructor, the keyword this references the new object that’s being created. Revisiting object creation, a basic constructor may look as follows:

function Car( model, year, miles ) {

  this.model = model;
  this.year = year;
  this.miles = miles;

  this.toString = function () {
    return this.model + " has done " + this.miles + " miles";

// Usage:

// We can create new instances of the car
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );

// and then open our browser console to view the 
// output of the toString() method being called on 
// these objects
console.log( civic.toString() );
console.log( mondeo.toString() );

The above is a simple version of the constructor pattern, but it does suffer from some problems. One is that it makes inheritance difficult and the other is that functions such as toString() are redefined for each of new object created using the Car constructor. This isn’t optimal, as the function should ideally be shared between all instances of the Car type.

Thankfully, as there are a number of both ES3- and ES5-compatible alternatives to constructing objects, it’s trivial to work around this limitation.

Constructors with Prototypes

Functions in JavaScript have a property called a prototype. When we call a JavaScript constructor to create an object, all the properties of the constructor’s prototype are then made available to the new object. In this fashion, multiple Car objects can be created that access the same prototype. We can thus extend the original example as follows:

function Car( model, year, miles ) {

  this.model = model;
  this.year = year;
  this.miles = miles;


// Note here that we are using Object.prototype.newMethod rather than 
// Object.prototype so as to avoid redefining the prototype object
Car.prototype.toString = function () {
  return this.model + " has done " + this.miles + " miles";

// Usage:

var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );

console.log( civic.toString() );
console.log( mondeo.toString() );

A single instance of toString() will now be shared between all Car objects.

The best content for your career. Discover unlimited learning on demand for around $1/day.