Firstly arguments.callee
is deprecated in ES5 strict so we don't use it. The real solution is rather simple.
You don't use new
at all.
var Make = function () {
if (Object.getPrototypeOf(this) !== Make.prototype) {
var o = Object.create(Make.prototype);
o.constructor.apply(o, arguments);
return o;
}
...
}
That's a right pain in the ass right?
Try enhance
var Make = enhance(function () {
...
});
var enhance = function (constr) {
return function () {
if (Object.getPrototypeOf(this) !== constr.prototype) {
var o = Object.create(constr.prototype);
constr.apply(o, arguments);
return o;
}
return constr.apply(this, arguments);
}
}
Now of course this requires ES5, but everyone uses the ES5-shim right?
You may also be interested in alternative js OO patterns
As an aside you can replace option two with
var Make = function () {
var that = Object.create(Make.prototype);
// use that
return that;
}
In case you want your own ES5 Object.create
shim then it's really easy
Object.create = function (proto) {
var dummy = function () {};
dummy.prototype = proto;
return new dummy;
};
Because it's a function that doesn't need to be called. new
is not that different from a regular function call in Javascript.
A constructor can do more than simply set fields. For instance, if it validates incoming data, then you will cause a validation
error when you were simply trying to set inheritance chain.
And you don't need Object.create
, this is sufficient:
function objectCreate( proto ) {
function T(){}
T.prototype = proto;
return new T();
}
Best Answer
It doesn't have a purpose. As you can see, it only annoys you without giving out any additional information. It only has a reason.
What's happening is that the structure you're printing has a cyclical reference (the prototype knows about the contructor, and the constructor knows about its prototype), and the logger isn't smart enough to realize it will never finish if it naively follows all references.