Liam McLennan

February 2011 Entries

JavaScript Class Patterns Revisited: Endgame

 

imageI recently described some of the patterns used to simulate classes (types) in JavaScript. But I missed the best pattern of them all. I described a pattern I called constructor function with a prototype that looks like this:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  toString: function() {
    return this.name + " is " + this.age + " years old.";
  }
};

var john = new Person("John Galt", 50);

console.log(john.toString());

and I mentioned that the problem with this pattern is that it does not provide any encapsulation, that is, it does not allow private variables. Jan Van Ryswyck recently posted the solution, obvious in hindsight, of wrapping the constructor function in another function, thereby allowing private variables through closure. The above example becomes:

var Person = (function() {
  // private variables go here
  var name,age;
  
  function constructor(n, a) {
    name = n;
    age = a;
  }

  constructor.prototype = {
    toString: function() {
      return name + " is " + age + " years old.";
    }
  };
  
  return constructor;  
})();

var john = new Person("John Galt", 50);
console.log(john.toString());

Now we have prototypal inheritance and encapsulation. The important thing to understand is that the constructor, and the toString function both have access to the name and age private variables because they are in an outer scope and they become part of the closure.

What ‘enterprise’ doesn’t understand about risk

Enterprises (large bureaucracies) obsess about risk. I think it is because of the inertia generated by the process and politics that they have to deal with.

The trouble is that they respond to risk in precisely the wrong way: by adding complexity. Need to call a method? Better wrap it in WCF service. Need to talk to another application? Better hook a message queue to a service bus connected to a biztalk sharepoint – on Oracle. Here is a simple guide:

Complexity increases risk. Simplicity reduces risk.

JavaScript Class Patterns

To write object-oriented programs we need objects, and likely lots of them.

JavaScript makes it easy to create objects:

var liam = {
  name: "Liam",
  age: Number.MAX_VALUE
};

But JavaScript does not provide an easy way to create similar objects. Most object-oriented languages include the idea of a class, which is a template for creating objects of the same type. From one class many similar objects can be instantiated.

cookie cutter

Many patterns have been proposed to address the absence of a class concept in JavaScript. This post will compare and contrast the most significant of them.

Simple Constructor Functions

Classes may be missing but JavaScript does support special constructor functions. By prefixing a call to a constructor function with the ‘new’ keyword we can tell the JavaScript runtime that we want the function to behave like a constructor and instantiate a new object containing the members defined by that function. Within a constructor function the ‘this’ keyword references the new object being created -  so a basic constructor function might be:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.toString = function() {
    return this.name + " is " + age + " years old.";
  };
}

var john = new Person("John Galt", 50);

console.log(john.toString());

Note that by convention the name of a constructor function is always written in Pascal Case (the first letter of each word is capital). This is to distinguish between constructor functions and other functions. It is important that constructor functions be called with the ‘new’ keyword and that not constructor functions are not.

There are two problems with the pattern constructor function pattern shown above:

  1. It makes inheritance difficult
  2. The toString() function is redefined for each new object created by the Person constructor. This is sub-optimal because the function should be shared between all of the instances of the Person type.

Constructor Functions with a Prototype

JavaScript functions have a special property called prototype. When an object is created by calling a JavaScript constructor all of the properties of the constructor’s prototype become available to the new object. In this way many Person objects can be created that can access the same prototype. An improved version of the above example can be written:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  toString: function() {
    return this.name + " is " + this.age + " years old.";
  }
};

var john = new Person("John Galt", 50);

console.log(john.toString());

In this version a single instance of the toString() function will now be shared between all Person objects.

Private Members

The short version is: there aren’t any. If a variable is defined, with the var keyword, within the constructor function then its scope is that function. Other functions defined within the constructor function will be able to access the private variable, but anything defined outside the constructor (such as functions on the prototype property) won’t have access to the private variable. Any variables defined on the constructor are automatically public. Some people solve this problem by prefixing properties with an underscore and then not calling those properties by convention.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  _getName: function() {
    return this.name;
  },
  toString: function() {
    return this._getName() + " is " + this.age + " years old.";
  }
};

var john = new Person("John Galt", 50);

console.log(john.toString());

Note that the _getName() function is only private by convention – it is in fact a public function.

Functional Object Construction

Because of the weirdness involved in using constructor functions some JavaScript developers prefer to eschew them completely. They theorize that it is better to work with JavaScript’s functional nature than to try and force it to behave like a traditional class-oriented language. When using the functional approach objects are created by returning them from a factory function. An excellent side effect of this pattern is that variables defined with the factory function are accessible to the new object (due to closure) but are inaccessible from anywhere else. The Person example implemented using the functional object construction pattern is:

var personFactory = function(name, age) {
  var privateVar = 7;
  return {
    toString: function() {
      return name + " is " + age * privateVar / privateVar + " years old.";
    }
  };
};

var john2 = personFactory("John Lennon", 40);
console.log(john2.toString());

Note that the ‘new’ keyword is not used for this pattern, and that the toString() function has access to the name, age and privateVar variables because of closure.

This pattern can be extended to provide inheritance and, unlike the constructor function pattern, it supports private variables. However, when working with JavaScript code bases you will find that the constructor function is more common – probably because it is a better approximation of mainstream class oriented languages like C# and Java.

Inheritance

Both of the above patterns can support inheritance but for now, favour composition over inheritance.

Summary

When JavaScript code exceeds simple browser automation object orientation can provide a powerful paradigm for controlling complexity. Both of the patterns presented in this article work – the choice is a matter of style. Only one question still remains; who is John Galt?

JavaScript Class Patterns

To write object-oriented programs we need objects, and likely lots of them.

JavaScript makes it easy to create objects:

var liam = {
  name: "Liam",
  age: Number.MAX_VALUE
};

But JavaScript does not provide an easy way to create similar objects. Most object-oriented languages include the idea of a class, which is a template for creating objects of the same type. From one class many similar objects can be instantiated.

cookie cutter

Many patterns have been proposed to address the absence of a class concept in JavaScript. This post will compare and contrast the most significant of them.

Simple Constructor Functions

Classes may be missing but JavaScript does support special constructor functions. By prefixing a call to a constructor function with the ‘new’ keyword we can tell the JavaScript runtime that we want the function to behave like a constructor and instantiate a new object containing the members defined by that function. Within a constructor function the ‘this’ keyword references the new object being created -  so a basic constructor function might be:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.toString = function() {
    return this.name + " is " + age + " years old.";
  };
}

var john = new Person("John Galt", 50);

console.log(john.toString());

Note that by convention the name of a constructor function is always written in Pascal Case (the first letter of each word is capital). This is to distinguish between constructor functions and other functions. It is important that constructor functions be called with the ‘new’ keyword and that not constructor functions are not.

There are two problems with the pattern constructor function pattern shown above:

  1. It makes inheritance difficult
  2. The toString() function is redefined for each new object created by the Person constructor. This is sub-optimal because the function should be shared between all of the instances of the Person type.

Constructor Functions with a Prototype

JavaScript functions have a special property called prototype. When an object is created by calling a JavaScript constructor all of the properties of the constructor’s prototype become available to the new object. In this way many Person objects can be created that can access the same prototype. An improved version of the above example can be written:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  toString: function() {
    return this.name + " is " + this.age + " years old.";
  }
};

var john = new Person("John Galt", 50);

console.log(john.toString());

In this version a single instance of the toString() function will now be shared between all Person objects.

Private Members

The short version is: there aren’t any. If a variable is defined, with the var keyword, within the constructor function then its scope is that function. Other functions defined within the constructor function will be able to access the private variable, but anything defined outside the constructor (such as functions on the prototype property) won’t have access to the private variable. Any variables defined on the constructor are automatically public. Some people solve this problem by prefixing properties with an underscore and then not calling those properties by convention.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype = {
  _getName: function() {
    return this.name;
  },
  toString: function() {
    return this._getName() + " is " + this.age + " years old.";
  }
};

var john = new Person("John Galt", 50);

console.log(john.toString());

Note that the _getName() function is only private by convention – it is in fact a public function.

Functional Object Construction

Because of the weirdness involved in using constructor functions some JavaScript developers prefer to eschew them completely. They theorize that it is better to work with JavaScript’s functional nature than to try and force it to behave like a traditional class-oriented language. When using the functional approach objects are created by returning them from a factory function. An excellent side effect of this pattern is that variables defined with the factory function are accessible to the new object (due to closure) but are inaccessible from anywhere else. The Person example implemented using the functional object construction pattern is:

var john = new Person("John Galt", 50);
console.log(john.toString());

var personFactory = function(name, age) {
  var privateVar = 7;
  return {
    toString: function() {
      return name + " is " + age * privateVar / privateVar + " years old.";
    }
  };
};

var john2 = personFactory("John Lennon", 40);
console.log(john2.toString());

Note that the ‘new’ keyword is not used for this pattern, and that the toString() function has access to the name, age and privateVar variables because of closure.

This pattern can be extended to provide inheritance and, unlike the constructor function pattern, it supports private variables. However, when working with JavaScript code bases you will find that the constructor function is more common – probably because it is a better approximation of mainstream class oriented languages like C# and Java.

Inheritance

Both of the above patterns can support inheritance but for now, favour composition over inheritance.

Summary

When JavaScript code exceeds simple browser automation object orientation can provide a powerful paradigm for controlling complexity. Both of the patterns presented in this article work – the choice is a matter of style. Only one question still remains; who is John Galt?

Stoicism

image Recently I have been reading about the ancient Greco-Roman philosophy Stoicism, which I encountered via Derek Sivers, Tim Ferriss and my reading of the New England transcendentalists.

The book I read is called A Guide to the Good Life: The Ancient Art of Stoic Joy by William B. Irvine. I liked it a lot, and I don’t want to lose what I have learnt, so I prepared the cheatsheet below.

stoicism_cheat_sheet

The Fast Way to Rebuild a Computer – Ninite.com

image Dear Future Me,

The next time you need to repave a Windows computer the link that you can never remember is ninite.com.

Ninite is an online service that lets you select the free tools that they like to have on their computer (Firefox, 7-zip, notepad++, skype etc) and builds a custom installer that will install them all. It will save you hours.

K.

Thanks.

Bye.

image