Given this code:
var reg = /a/g;
console.log(reg.test("a"));
console.log(reg.test("a"));
I get this result:
true
false
I have no idea how this could happen. I have tested in both Node.js (v8) and Firefox browser.
To workaround the problem, you can remove the g
flag or reset lastIndex
as in
var reg = /a/g;
console.log(reg.test("a"));
reg.lastIndex = 0;
console.log(reg.test("a"));
The problem arises because test
is based around exec
which looks for more matches after the first if passed the same string and the g
flag is present.
15.10.6.3
RegExp.prototype.test(string)
# Ⓣ ⓇThe following steps are taken:
- Let match be the result of evaluating the
RegExp.prototype.exec
(15.10.6.2) algorithm upon thisRegExp
object using string as the argument.- If match is not
null
, then returntrue
; else returnfalse
.
The key part of exec
is step 6 of 15.10.6.2:
6. Let global be the result of calling the [[Get]] internal method of R with argument "global".
7. If global is false, then let i = 0.
When i
is not reset to 0, then exec
(and therefore test
) does not start looking at the beginning of the string.
This is useful for exec
because you can loop to handle each match:
var myRegex = /o/g;
var myString = "fooo";
for (var match; match = myRegex.exec(myString);) {
alert(match + " at " + myRegex.lastIndex);
}
but obviously it isn't so useful for test
.