関数とは
Function を new したものというイメージがありますが。厳密にはオブジェクトに
[[Call]]
という内部プロパティが、ある→「関数」、ない→「関数じゃない」、ということになっています。関数がオブジェクトかどうかはプロトタイプやコンストラクタとは無関係です。
つまり typeof は内部プロパティ Call を参照することによって関数か関数でないかを判断しているということなんです。
例えば
(IE では動かないです。)
var f = new Function('alert("Hello!")');
f.__proto__ = Object.prototype;
alert(typeof f);
f();
このように、プロトタイプを差し替えても f は function なのです。
最近知ったのですが。Firefox では、 RegExp も関数のようだ。
var r = /(a)/;
r.__proto__ = Object.prototype;
alert(typeof r);
alert(r('amachang'));
つまり、コンストラクタ RegExp ではインスタンスに内部プロパティ Call を与えているのだ。
例えば
これを
['hoge', 'oge', 'poge'].every(function(t){
return (/oge$/).test(t);
});
こうできる
['hoge', 'oge', 'poge'].every(/oge$/);
めっちゃシンプル!まあ、 Firefox Only なんで、 XUL とかで使うかなあ。
ちなみに
多くの関数は new することができるが、RegExp はできない。内部プロパティ
[[Construct]]
がないからである。
var f = function(){};
var r = /a/;
new f;
new r;