質問: test_reg.test(list.toLocaleLowerCase()); console.log(list + 'の時、if前は' + test_result); if (test_result){ console.log(list + 'の時、if後は' + test_reg.test(list.toLocaleLowerCase())); } } ``` に変更すると、(正規表現による探索結果を変数に代入し、その変数を利用するようにしています。ifの中は正規表現による結果をそのままconsoleする設定です。) ``` 4.3.1 3 4.3.1の時、if前はtrue 4.3.1の時、if後はfalse 4.3.2 3 4.3.2の時、if前はtrue 4.3.2の時、if後はfalse 4.3.3 3 4.3.3の時、if前はtrue 4.3.3の時、if後はtrue ``` というように、if内に入る流れは想定通りの実行がなされます。 しかし、if内部では、元々trueだった探索結果がfalseになっています。 つまり、else if内でtest_reg.test(list.toLocaleLowerCase())の結果がif前後で変化しているのですが、これはなぜでしょうか。理由がわかりません。 forEachで他の要素を参照して、listが書き換えられてしまって結果が変わってしまったのかとも思っていますが、forEachの仕様のページ(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/foreach)を確認してもそのような、各要素を見ている途中に他の要素に飛ぶというような記載を見つけることができませんでしたし、listの値は変更されていない(if前とif後で参照している数字が変わっていない)ので、そうではないと思います。 実装としては変更後のやり方で目的は達成できるので良いのですが、気になるので、教えていた開けると嬉しいです。 よろしくお願いします。
回答: RegExpオブジェクトをグローバルサーチ(g)で複数回使用する場合に、オブジェクト内部のlastIndexプロパティの値が更新されます。 RegExp.lastIndex - JavaScript | MDN - Mozilla > > このプロパティは、正規表現が、グローバルサーチを示す "g" を使用した場合にのみ、セットされます。 or the "y" flag to indicate a sticky search. 以下のルールが適用されます。: > > ・lastIndex が文字列の長さよりも大きければ、test() 及び exec() は失敗し、lastIndex は 0 にセットされます。 > > ・lastIndex が文字列の長さと等しく、かつ、正規表現が空文字列にマッチする場合には、正規表現は lastIndex の始まりの入力にマッチします。 > > ・lastIndex が文字列の長さと等しく、かつ、正規表現が空文字列にマッチしない場合、正規表現は入力にマッチせず、lastIndex は 0 にリセットされます。 > > ・それ以外の場合は、lastIndex は直近のマッチに続く次の位置にセットされます。 > > > ↑ここでは最後のルールに基づき、複数回実行されたtestメソッドでlastIndexの値が更新されていきます。 その後、最初のルールに基づき、lastIndexが文字列の長さよりも後ろにセットされ、testメソッドが失敗します。 ``` var test_reg = new RegExp('.3' , 'g'); // 1回目 console.log(test_reg.test("4.3.3")); //true console.log(test_reg.lastIndex); // 3 // 2回目 console.log(test_reg.test("4.3.3")); //true console.log(test_reg.lastIndex); // 5 // 3回目 console.log(test_reg.test("4.3.3")); //false console.log(test_reg.lastIndex); // 0 <- 最初のルールが適用される ```