Functionにまつわる変態的検証。
JavaScriptの不思議な言語構造、Function。
どうなるか気になる挙動があったので確認してみた。
Functionをnewするときとcallするときでthisってどうなるの?
まずFunctionが何かっていうと、
var f = function() {};
のようにして作られる「関数型オブジェクト」のこと。
Perlの無名関数のように、そのままcallすることができる。
f();
JavaScript独特の挙動として、このFunctionオブジェクトはクラスのようにも振る舞う。
var o = new f();
とすると、oには「fというクラスのインスタンス」とも言えるオブジェクトが入る。
その他prototypeが云々というのもあるが、今回の件とは関係ないので割愛。
そして本題へ
今回の主旨は、「関数としてもコンストラクタとしても呼べるFunctionを両方の呼び方したらthisの値はどうなるのか」を検証すること。
まずは以下のコード。
var f = function() { alert((this === window)); }; f(); // true new f(); // false
windowのコンテキストで単に呼ぶとthisがwindowになる。
これは普通の挙動として知ってはいた。
本命は以下。
var f = function() { alert((this === window)); }; var Foo = new function() {}; Foo.prototype.normal = function() { f(); }; Foo.prototype.create = function() { new f(); }; var foo = new Foo(); foo.normal(); // true foo.create(); // false
他クラスのインスタンスのコンテキストで呼んでみたらwindowじゃなくてインスタンスがthisになるんじゃないかと思ったけど、
そうでもないらしい。
どこから呼ぼうとapplyなどでコンテキストを明示しない限りwindowをthisとして実行されるようだ。
つまり、if (this === window)でコンストラクタとして呼ばれたかどうかが分かるわけで・・・フフフ