質問: new RegExp(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/gi); であり、そのインスタンスpがプロトタイプを辿ってexecメソッドを呼び出している と理解しております。 code2>> 理解ができないのは document.write(RegExp.leftContext);//code2 です。 1.まずせっかくpインスタンスを作ったのに、直接RegExpオブジェクトにアクセスするのでしょうか?静的プロパティというのが関連しているというところまで調べることができたのですが、詳しい内容は理解ができませんでした。。 2.実際にはp.leftContextでは正規表現でマッチする前までの文字列は取得できないのですが、インスタンスからこのleftContextプロパティにはアクセスできないのはなぜでしょうか? 3.pインスタンスは/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/giというリテラル(引数?情報?)を知っているので、 result=p.exec(str);//code1 document.write(result); の結果、正規表現にマッチする内容を配列で返してくれるのは非常に理解できるのですが、一方でオブジェクトのRegExpは/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/giを知らない(引数?として持っていない)はず、加えてstrについても何も伝達していないはずなのに document.write(RegExp.leftContext)で 対象の文字列や正規表現を認識しているのはなぜでしょうか? pで作成するようなインスタンスの場合、元のオブジェクト等に影響を与えないようにインスタンスを作成していると理解しているのですが、なぜまたはどのようにして、インスタンスしか知りえない情報をRegExpオブジェクトは保有(または参照)しているのでしょうか? また、素人のため、うまく質問できていないかもしれず、申し訳ございませんが、 不明な点からあれば、ご指摘いただければ、補足させていただきます。 よろしくお願い申し上げます。 ``` ```
回答: `RegExp`はRegExp**コンストラクタ**です。`p`はRegExpオブジェクトであり、別の表現をすると、RegExpコンストラクタのインスタンスです。なお、JavaScriptではコンストラクタはオブジェクトであり、また、関数でもあります。 `RegExp.leftContext`はRegExpコンストラクタのプロパティです。これは「最も直前に正規表現を使ってマッチするかどうかの検索をしたときに、マッチした部分の左側が自動的に入る」というプロパティになっています。つまり、`result=p.exec(str)`が「正規表現を使ってマッチするかどうかの検索」にあたり、これが「最も直前に」あたります。この検索でのマッチするのは"http://..."ですので、そのマッチ部分よりも左側、つまり、マッチする前の部分を抜き出すことができます。 このようにコンストラクタには、個々のインスタンスとは独立して操作するためのプロパティやメソッドが用意されています。今回の例では「**最も直前に**」というのが動作の仕様にあり、その前の検索がどのようなRegExpオブジェクトであったかは関係が無い動作になります。これらは、インスタンスとは結びついていないため、インスタンスから呼び出すことはできません。 なお、`RegExp.leftContext`は非標準の機能であり、各ブラウザで実装はされていますが、使用することは非推奨となっています。ですが、これは元々Perlの正規表現には備わっている機能であるため、Perlと同じように実装したのだと思われます。(同じような物がRubyにもありますし、これもPerlからの導入です。Perlの正規表現は実用的でかつよくできていて、また、広く広まっていることもあり、JavaScriptを含めた多くの実装で参考にされています)