0

I have the following two js example codes, one using literal regexp and the other one using RegExp object:

"use strict";

var re;


// literal regexp
for(var i = 0; i<10; i++)
{
    re = /cat/g;
    console.log(re.test("catastrophe"));
}

// RegExp constructor
for(var i = 0; i<10;i++)
{
    re = new RegExp("cat", "g");
    console.log(re.test("catastrophe"));
}

Some books say that using the first example "true" should be printed on each second iteration given the fact that the using the literal expression there will be created only one instance of RegExp. So the loop finds on the first run the substring "cat", than on the second run continues from where is left and finds nothing. On the third run it starts from the beginning and so on. I've tested this but it seems that in both examples i get the count of 10.

Can you explain why this is happening?

2 Answers 2

6

The 3rd Edition ECMAScript (JavaScript) specification allowed caching and reusing regular expression literals, including their state, leading to the "surprising" behavior you mention in relation to your first code example, which certainly looks like it should create a new regular expression object on every loop. That caching of literals was not implemented by most engines and was a phenomenally bad idea, and the 5th Edition specification fixes it.

I believe all modern engines that used to do caching (primarily SpiderMonkey, Firefox's engine) were updated accordingly. A new regex is created for every iteration in both of your examples.

More in this blog post (right at the end) by Steven Levithan, and in the fourth paragraph of Annex E in the specification:

7.8.5: Regular expression literals now return a unique object each time the literal is evaluated. This change is detectable by any programs that test the object identity of such literal values or that are sensitive to the shared side effects.

Sign up to request clarification or add additional context in comments.

2 Comments

so if i don't need IE8 i can use any of the two forms?
@TudorRavoiu: IE8 wasn't one of the engines that cached them, so it's fine too. Try it here: jsbin.com/wopuy/1 I think it was mostly SpiderMonkey (Firefox's engine), which has long since been fixed.
0

In both cases, you are creating a new RegExp each time through the for loop. It doesn't matter which way you declare the RegExp - it's still creating a new one each time the loop iterates. Thus, you get the same behavior.

Now, if you initialized the re variable before the for loop, you would get a different behavior because of the persistence of the same RegExp object and how it uses the g flag.

1 Comment

That's all true now, as of ES5. ES3 had this weird concept of "caching" literals that only one or two engines ever implemented, which lead to the behavior the OP describes for the first loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.