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