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
February 21st, 2010 at 8:38 pm
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.
November 8th, 2010 at 1:02 pm
function MyClass(name) {
if (!(this instanceof MyClass)) return new MyClass();
this.name = name;
// more initialisation
return this;
}
December 16th, 2011 at 12:33 am
Just added this blog to my favorites. I enjoy reading your blogs and hope you maintain them coming!