<script type="text/javascript"> function doRex(){ var example = "J'adore Firefox!"; // I like Firefox! var RE = /Fire/g; var result = RE.exec(example); if(result) alert("マッチ: " + result + "¥nlastIndex: " + RE.lastIndex); else alert("マッチしません!:" + "¥nlastIndex: " + RE.lastIndex); } </script> <button onclick="doRex();"> 実 行 1 </button>
上のdoRex()関数を実行すると、最初ボタンを押したときはちゃんとマッチしますが、2回目にボタンを押したときの結果がブラウザで異なります。Firefox3.0.7, Chrome1.0, Opera9.64では、「マッチしない」、IE6-8とSafari4 public betaでは、マッチして1回目と同じ結果です。なぜ、こういうことになるかというと、lastIndex絡みです。1回目の実行に対して、lastIndexの値が保持されているからです。2回目の実行で、マッチしないとなると、RE.lastIndexはまた0に戻るので、3回目の結果は初回と同じく「マッチ」です。
でも、疑問なのが、doRex()という関数の中で定義したローカルな変数だから、doRex()を実行する度に、lastIndexの値はリセットされるのが正しい気もするんだけどなぁ。doRex()の中ではなく、グローバルな空間で同様のことをやれば、SafariもIEも2回目は「マッチしない」となり、これは納得できる挙動なんですが。
では、このブラウザ間の差異をなくすにはどうするか?ひとつは、RE.exec(example) した後に、RE.lastIndex = 0; // 値をリセットという記述を加えて、明示的にlastIndexを元に戻す方法。もうひとつは、new演算子を使う方法です。これなら、どのブラウザでも同じ挙動、何度ボタンを押しても、「マッチ」となります。new RegExp("foo", "g") と /foo/g って同じと思っていたんだけど。
<script type="text/javascript"> function doRex2(){ var example = "J'adore Firefox!"; // I like Firefox! var RE2 = new RegExp("Fire", "g"); // new演算子を使用する var result2 = RE2.exec(example); if(result2) alert("マッチ: " + result2 + "¥nlastIndex: " + RE2.lastIndex); else alert("マッチしません!:" + "¥nlastIndex: " + RE2.lastIndex); } </script> <button onclick="doRex2();"> 実 行 2 </button>
上のコードであれば、ブラウザ間の差異がない。
でも、Safari/IE と Firefox/Chrome/Opera、どっちが正しい挙動なんだろうな。今イチ、すっきりしないです。
Comments