JavaScript new operator considered harmful

tl;dr: it binds implementation details to an interface

In this blog post I argue why the new operator should not be used in a public interface.

Why? It introduces change resistance

Let’s say that you’re writing a zoo module for Node. The module has all sorts of animals, from giraffes to ducks, but for the first version you decide to only include dogs. So the interface looks like this:

var dog = new zoo.Dog()

So you ship the code and people start happily using your library. Inspired by its success, you decide to add support for zebras and buffalo. You start writing new code and soon realize you’d afford more flexibility by defining an Animal object that has an AnimalType object.

var dog = new zoo.Animal(new zoo.Dog())

Alas you’ve already published code that relies on instantiating Dogs so you either need to break backwards compatibility or live with what you have. Oh well.

The solution

Use factory functions over direct instantiation.

function Dog() {
return new function() {
this.bark = function() {
console.log(“Woof!”)
}
}
}

Or better yet, use object literals over instances:

function Dog() {
return {
bark: function() {
console.log(“Woof!”)
}
}
}

This affords you the luxury of changing the implementation of Dog around in any way you like without changing the interface. As a bonus, the interface is simpler since you don’t need the new operator to work with the library.