Tudor Ravoiu
Tudor Ravoiu

Reputation: 2150

Javascript literal regexp vs RegExp object, instances inside loops

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?

Upvotes: 0

Views: 216

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

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.

Upvotes: 6

jfriend00
jfriend00

Reputation: 707456

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.

Upvotes: 0

Related Questions