views:

118

answers:

3

Is it better to use the RegExp object or the inline style? And why?

+2  A: 

As per J-P's answer there is a slight difference, which sometimes could be important. The intent was that:

var re = /\d+/;

be the same as:

var re = new RegExp("\\d+");

but, oddly, in Firefox/Chrome it isn't quite the same (as demonstrated by his example with stateful expressions that are used multiple times).

So, use the RegExp object would be my advice. And an excellent find by J-P.

That being said, the major circumstance where you had to use RegExp over the literal syntax anyway was to dynamically create expressions, for example:

var s = "[asdf]+";
var re = new RegExp(":" + s + ":", "g");
cletus
There is gotta be more defined difference. My motivation for asking this question was because JSLint seems to dislike the inline format. Unfortunately I could not find an understandable reason as to why.
Proof of Concept
JSLint doesn't like a lot of things which are virtually identical. Remember that JSLint is a *style* checker, not just a syntax checker. It is most likely frowned upon by Mr Crockford because it could be difficult to understand or something similar.
nickf
+3  A: 

"The RegExp() method allows you to dynamically construct the search pattern as a string, and is useful when the pattern is not known ahead of time." -http://www.javascriptkit.com/jsref/regexp.shtml

a432511
+9  A: 

According to the ES3 specification, they are slightly different in that the literal syntax (/regex/) will create a single RegExp object upon the initial scan:

A regular expression literal is an input element that is converted to a RegExp object (section 15.10) when it is scanned. The object is created before evaluation of the containing program or function begins. Evaluation of the literal produces a reference to that object; it does not create a new object.

The error in that spec was acknowledged in ES4:

In ES3 a regular expression literal like /ab/mg denotes a single unique RegExp object that is created the first time the literal is encountered during evaluation. In ES4 a new RegExp object is created every time the literal is encountered during evaluation.

Implementations vary across browsers. Safari and IE treat literals as per ES4, but Firefox and Chrome appear to treat them as per ES3.

Try the following code in various browsers and you'll see what I mean:

function f() {
    return /abc/g.test('abc');
}

alert(f()); // Alerts true
alert(f()); // Alerts false in FF/Chrome

Compared with:

function f() {
    return RegExp('abc', 'g').test('abc');
}

alert(f()); // Alerts true
alert(f()); // Alerts true

Note, false is alerted because the function is still using the regex from the previous call of that function, the lastIndex of which was updated, meaning that it won't match the string "abc" anymore.


Tip: the new operator is not required for RegExp to be instantiated. RegExp() by itself works the same...


More info on the ES3/4 issue: http://stackoverflow.com/questions/1534098/regex-lastindex-unexpected-behaviour

J-P
That's f'ing interesting, man. That's f'ing interesting.
Crescent Fresh
So, you can argue that using the inline form will be slightly more efficient (at least in ES3). Whereas the RegExp form would produce a more consistent cross-implementation result. Awesome!
Proof of Concept
+1 good find/answer
cletus