Skip to content

new-Agnostic JavaScript Constructors

Posted on:August 8, 2015

Constructors in JavaScript have gotten a bad rep because there’s nothing stopping the unwitting programmer from doing something like this:

function Thing(x, y) {
  this.x = x;
  this.y = y;
}
 
var thing = Thing(1, 2);
console.log(thing); // undefined
console.log(this); // window (or equivalent global object)
console.log(this.x); // 1
console.log(this.y); // 2

I wrote comprehensively about object creation here, which may be useful to read as a prerequisite to this post.

This tip from Item 33 of Effective JavaScript by David Herman makes your constructor behave as intended, regardless of whether the new keyword is present. The first method:

function Thing(x, y) {
  if (!(this instanceof Thing)) {
    return new Thing(x, y);
  }
  this.x = x;
  this.y = y;
}

An alternative method to save that extra recursive function call:

function Thing(x, y) {
  var self = this instanceof Thing ? this : Object.create(Thing.prototype);
  self.x = x;
  self.y = y;
  return self;
}