IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

Firefox では RegExp って関数だったのね

関数とは

Function を new したものというイメージがありますが。厳密にはオブジェクト

[[Call]]

という内部プロパティが、ある→「関数」、ない→「関数じゃない」、ということになっています。関数がオブジェクトかどうかはプロトタイプやコンストラクタとは無関係です。
つまり typeof は内部プロパティ Call を参照することによって関数か関数でないかを判断しているということなんです。

例えば

(IE では動かないです。)

var f = new Function('alert("Hello!")');
f.__proto__ = Object.prototype;
alert(typeof f);
f();

このように、プロトタイプを差し替えても f は function なのです。

RegExp も実は関数

最近知ったのですが。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$/); // true

めっちゃシンプル!まあ、 Firefox Only なんで、 XUL とかで使うかなあ。

ちなみに

多くの関数は new することができるが、RegExp はできない。内部プロパティ

[[Construct]]

がないからである。

var f = function(){};
var r = /a/;

new f; // ok!
new r; // error!!