JavaScript のコンストラクタ関数
new つけてもつけなくてもいいようにするにはどう書くのがベストか的なんだろう。Deferred ではこうしたけど
function Deferred () { return (this instanceof Deferred) ? this.init(this) : new Deferred() }
// prototype.init では this をかえしてる。
// でもコンストラクタは Object をかえした場合にしかその返り値を使わないので undefined でもべつにいい。汎用的にするなら
function Foo () {
if (this instanceof arguments.callee)
this.init(this);
else
return new arguments.callee;
}かな。ただ、これだと任意の数の引数がとれない (new は括弧をつけなくていいことからも解るように関数呼びだしではないので)。
function Foo () {
if (this instanceof arguments.callee) {
this.init.apply(this, arguments);
} else {
// new のエミュレート
var f = function () {};
f.prototype = arguments.callee.prototype;
var o = new f;
arguments.callee.apply(o, arguments);
return o;
}
}どうみても素直に引数リストを書いたほうがよみやすくていい。(instanceof (がつかっている [[HasInstance]]) は [[Prototype]] をみる。new 以外に [[Prototype]] をセットする方法はない。)
てかはてなで
[[Prototype]] [] [[Prototype]] [] <- リンクはされないけど括弧が消える。
を地で書くにはどうしたらいいんだ……
ちなみに global ( (function () { return this })() ) と、this をくらべるのはよくないことがある。
jQuery Deferred だと $.deferred = Deferred とやっているわけだけど、この場合 this は $ (jQuery) になってしまうのでだめ。