4

Why is Chrome's console displaying /(?:)/ for the RegExp's prototype?

console.log(RegExp.prototype);
console.log(/a/.__proto__);

Is this something implementation specific? IE is displaying //.

This is just a question out of curiousity. I tried to view all prototype methods of regular expressions in javascript, when I encountered this. Of course I found other ways of looking up those methods, but this keeps me wondering why this result is displayed.

I hope this question has not been asked before - did not find anything on Stackoverflow. Thanks!

2
  • (?:) i a empty group that doesn't give a match: "hello".replace(/(?:hello)/, "$1"); // "$1" While "hello".replace(/(hello)/, "$1"); // "hello" Commented Aug 19, 2013 at 12:59
  • @NULL: (?:) is a non-capture group. Commented Aug 19, 2013 at 13:02

1 Answer 1

6

Relevant section from spec

The RegExp prototype object is itself a regular expression object; its [[Class]] is "RegExp". The initial values of the RegExp prototype object’s data properties (15.10.7) are set as if the object was created by the expression new RegExp() where RegExp is that standard built-in constructor with that name.

Then we go to new RegExp() section, which is same as calling it with the empty string. So now we have empty regex object as the prototype.

The string representation is defined to be:

Return the String value formed by concatenating the Strings "/", the String value of the source property of this RegExp object, and "/"; plus "g" if the global property is true, "i" if the ignoreCase property is true, and "m" if the multiline property is true.

NOTE The returned String has the form of a RegularExpressionLiteral that evaluates to another RegExp object with the same behaviour as this object.

It ultimately comes down to .source property (explained in the new RegExp section), which is implementation defined as long as it behaves the same when used as regex:

Let S be a String in the form of a Pattern equivalent to P, in which certain characters are escaped as described below. S may or may not be identical to P or pattern; however, the internal procedure that would result from evaluating S as a Pattern must behave identically to the internal procedure given by the constructed object's [[Match]] internal property.

Since new RegExp("(?:)") and new RegExp("") behave identically, both chrome and IE are following the spec correctly. The spec even mentions this specific situation as an example:

If P is the empty String, this specification can be met by letting S be "(?:)"

Chrome's way can be considered "better" since it appears to work as regexp literal as well: /(?:)/ is a valid regex literal whereas // starts a one-line comment.

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

7 Comments

BTW, there is a string in spec saying "If P is the empty String, this specification can be met by letting S be "(?:)"."
Thanks, just the perfect answer. I will have a look at the spec, thanks for the link - I will already accept your answer as you pointed exactly out what i was looking for.
Might be worth pointing out that in JavaScript syntax, if you want to type a RegExp literal, // won't work because it will become a comment, whereas /(?:)/ will work, despite them both meaning the same thing in terms of RegExp.
However, RegExp.prototype instanceof RegExp is false.
@plalx instanceof is defined as Is [[rhs]].prototype in the prototype chain of [[lhs]]? and the answer is no since the spec says that the [[prototype]] of RegExp.prototype is is the standard built-in Object prototype object
|

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.