Enforcing `new` in constructors

A constructor is just a function and failing to invoke a constructor with new leads to errors. Not syntax errors but logical errors. Following a naming convention can certainly help, but it doesn't enforce the correct behavior. If you invoke a constructor without new, then this will refer to the global object, called window in browsers.

Here's a pattern that helps you make sure your constructor always behaves as constructor. Instead of adding all members to this, you add them to that.

In this implementation that is the same as this unless this is window which means someone forgot to use new.

function Person() {
  var that = (this === window) ? {} : this;

  that.name = name;
  that.say = function() {
    return "I am " + that.name;
  };

  return that;
}

window is only in browsers

Another way, if you work in non-browser environment is to check if this is an instance of your Person constructor.

Or name-agnostic, general-purpose way is to use arguments.callee instead of hard-coding the constructor name.

this instanceof Person
this instanceof arguments.callee

Tags: ,

3 Responses to “Enforcing `new` in constructors”

  1. Phoscur Says:

    function Constructor() {
    var that = (this === window) ? {} : this;

    return that;
    }
    I hope you aren’t serious with this. It just doesn’t make sense, as JavaScript always invokes the function as a non-constructor (if you put a new before just doesn’t matter) because it returns something. The condition is always true and thereby unneeded.

  2. Mira Says:

    function MyClass(name) {
    if (!(this instanceof MyClass)) return new MyClass();

    this.name = name;
    // more initialisation

    return this;
    }

  3. Dre Beats Headphones Says:

    Just added this blog to my favorites. I enjoy reading your blogs and hope you maintain them coming!

Leave a Reply