Warning: This is a long post. Let\'s keep it simple. I want to avoid having to p
ID: 641886 • Letter: W
Question
Warning: This is a long post.
Let's keep it simple. I want to avoid having to prefix the new operator every time I call a constructor in JavaScript. This is because I tend to forget it, and my code screws up badly.
The simple way around this is this...
function Make(x) {
if ( !(this instanceof arguments.callee) )
return new arguments.callee(x);
// do your stuff...
}
But, I need this to accept variable no. of arguments, like this...
m1 = Make();
m2 = Make(1,2,3);
m3 = Make('apple', 'banana');
The first immediate solution seems to be the 'apply' method like this...
function Make() {
if ( !(this instanceof arguments.callee) )
return new arguments.callee.apply(null, arguments);
// do your stuff
}
This is WRONG however -- the new object is passed to the apply method and NOT to our constructor arguments.callee.
Now, I've come up with three solutions. My simple question is: which one seems best. Or, if you have a better method, tell it.
First
Explanation / Answer
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;
};
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.