typeof 演算子と RegExp オブジェクト
Fx3 の MozRepl の search メソッドが動かないなーと思っていて調べた内容です。
ちなみに仕様的なものを引っ張って来ていますが、JSは門外漢なので自己責任でお願いします(ぇ
repl.search() の実装
function search(criteria, context) { context = context || this._workContext;var matcher; if (typeof criteria == "function") { matcher = criteria; } else { matcher = function (name) { return name == criteria; }; } for (var name in context) { if (matcher(name)) { this.print(name); } } }
ってな具合で、repl.search(regex, obj)やらrepl.search(func, obj)みたいに使えるハズ。
typeof regexの挙動
11.4.3 typeof 演算子 (The typeof Operator) によれば、
Object (native and doesn't implement [[Call]]) "object" Object (native and implements [[Call]]) "function" Object (host) Implementation-dependent
とある。ここで言う[[Call]]とは、8.6.2 内部プロパティとメソッド にある内部プロパティの事で、
プロパティ パラメータ 説明 [[Call]] 呼出側が提供する引数値のリスト オブジェクトに関連するコードを実行する。 関数呼出の式 (expression) を経由して呼出される。 この内部メソッドを実装するオブジェクトは関数 (function) と呼ばれる。
まぁ [[Call]] 内部プロパティを持てば関数呼び出し可能だよと言う事で良さそう。
ところで、
必須の内部プロパティに加えて、各ファンクション実体は [[Call]] プロパティ、 [[Construct]] プロパティ、 [[Scope]] プロパティ (8.6.2 及び 13.2 を参照) を持つ。[[Class]] プロパティの値は "Function" である。
とあるように Function インスタンスはもちろん呼び出し可能なのだが、15.10.7 RegExp インスタンスのプロパティ (Properties of RegExp Instances) には [[Call]] プロパティは存在しない。つまり呼び出し可能では無いのが ECMAScript 3rd 的には正しいと思われるが、実際には Firefox や Safari では呼び出せる模様。
が本来正しいと思われます。でFx2, Fx3での結果をそれぞれ並べると、
browser | typeof | call | |||
Fx2 | function | 出来る | |||
Fx3 | object | 出来る |
となっていて、まぁ何とも言えない状況みたい。
まとめ
id:amachangがきっと補足してくれます。
それはともかくtypeofでregexを期待する変数のチェックはダメです。Fxオンリーでいいなら、
typeof regex == "function" || regex.__proto__ == RegExp.prototype
などで判別すると良さそう。
かしこ。
追記
判定は普通にinstanceof RegExpでももちろんおkです。(thanks id:ku0522)