typeof for RegExp
Solution 1
You can use instanceof operator:
var t = /^foo(bar)?$/i;
alert(t instanceof RegExp);//returns true
In fact, that is almost the same as:
var t = /^foo(bar)?$/i;
alert(t.constructor == RegExp);//returns true
Keep in mind that as RegExp is not a primitive data type, it is not possible to use typeof
operator which could be the best option for this question.
But you can use this trick above or others like duck type checking, for example, checking if such object has any vital methods or properties, or by its internal class value (by using {}.toString.call(instaceOfMyObject)
).
Solution 2
alert( Object.prototype.toString.call( t ) ); // [object RegExp]
This is the way mentioned in the specification for getting the class of object.
From ECMAScript 5, Section 8.6.2 Object Internal Properties and Methods:
The value of the [[Class]] internal property is defined by this specification for every kind of built-in object. The value of the [[Class]] internal property of a host object may be any String value except one of "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", and "String". The value of a [[Class]] internal property is used internally to distinguish different kinds of objects. Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString (see 15.2.4.2).
A RegExp is a class of object defined in the spec at Section 15.10 RegExp(RegularExpression)Objects:
A RegExp object contains a regular expression and the associated flags.
Solution 3
Give the .constructor
property a whirl:
> /^foo(bar)?$/i.constructor
function RegExp() { [native code] }
> /^foo(bar)?$/i.constructor.name
"RegExp"
> /^foo(bar)?$/i.constructor == RegExp
true
Solution 4
From underscore.js
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
};
Solution 5
Works in google chrome:
x = /^foo(bar)?$/i;
x == RegExp(x); // true
y = "hello";
y == RegExp(y); // false
Related videos on Youtube
tau
Updated on January 28, 2022Comments
-
tau over 2 years
Is there anyway to detect if a JavaScript object is a regex?
For example, I would like to do something like this:
var t = /^foo(bar)?$/i; alert(typeof t); //I want this to return "regexp"
Is this possible?
Thanks!
EDIT: Thanks for all the answers. It seems I have two very good choices:
obj.constructor.name === "RegExp"
or
obj instanceof RegExp
Any major pros/cons to either method?
Thanks again!
-
user113716 over 13 years
-
TOPKAT over 4 yearsHi, I don't think putting answers in your question is very relevant. Please consider to add your own answer if you think you can add something useful :)
-
-
tau over 13 yearsawesome. do you know which is faster/more compatible: using your instanceof method or the constructor.name method? thanks!
-
Cleiton over 13 yearsinstanceof, of course, you can verify it yourself using Firebug Timing(console.time)
-
Tim Down over 13 yearsThose two code snippets are not identical. If you inserted the line
t.constructor = function() {};
, which is perfectly legal, thent instanceof RegExp
will still be true butt.constructor == RegExp
will be false. Usinginstanceof
is therefore preferable. -
Tim Down over 13 yearsThe
constructor
property can be changed.instanceof
does not have this problem and is a better solution. -
Tim Down over 13 yearsAlso,
t instanceof RegExp
will report false when testing a regular expression object from another window, which won't be a problem if this kind of check is not required, but is something to be aware of. -
Tim Down over 13 yearsThat's a misleading answer. A regular expression most definitely is a native ECMAScript and JavaScript object. I think what you're getting at is that typeof's possible values do not include a dedicated value for regular expression.
-
Tim Down over 13 yearsThey're duck typing here because
typeof
is unreliable for regexes andinstanceof
suffers from the cross-window problem. I wonder why they're not using @patrick dw's answer... -
user113716 over 13 years@Tim - I'm pretty sure. Not that it's any guarantee, but it is the method jQuery uses, including for RegExp. I'll just did a quick test in IE6 using a RegExp, and it does work (if that's any indicator). :o) Appears as though this method made it into the spec in the 3rd edition.
-
Tim Down over 13 yearsUnfortunately this doesn't work in IE with RegExp objects from other windows, for the same reason that the
[object Array]
check doesn't work for arrays. See jsfiddle.net/F6d8u for a demo and groups.google.com/group/comp.lang.javascript/browse_frm/thread/… for a discussion of this. -
Tim Down over 13 yearsNow I know: it doesn't work in IE when examining objects from other windows.
-
Tim Down over 13 yearsApart from duck typing, which is irritatingly inexact, this is still the best answer.
-
user113716 over 13 years@Tim - Interesting. I'm going to take a closer look at the example and article in a little bit when I have a chance to fire up IE again. Thanks for the input.
-
Sean Vieira over 13 years@Tim -- awesome ... I was wondering the same thing, but didn't have time to check yet. Thanks for posting the answer here!
-
nickf almost 11 yearsUnderscore now uses
Object.prototype.toString.call(obj) == '[object RegExp]'
-
sebilasse about 9 yearsAlso, when using in "if/else if" and you checked before for (typeof t === 'object') : add either -> && !(_t instanceof RegExp) to this check or if possible perform Cleiton's check first. [tl;dr : it is also typeof object, just important if used in "if/else if" ...]
-
Tino over 8 yearsI do not understand your answer.
-
Tino over 8 years
sed -i s/native/primitive/
. If you countobject
as primitive,typeof t
only outputs the primitive type name (well. mostly. see developer.mozilla.org/de/docs/Web/JavaScript/Reference/…). -
Paul Sweatte over 8 years@Tino RegExp types have two unique characteristics. The literal values start and end with the
/
character. The constructor instances have thesource
,global
,ignoreCase
,multiline
, andlastIndex
properties. -
Tino over 8 yearsThanks, but unfortunately following
frog
proves that these characteristics are not unique toRegExp
s:$$=function(){};$$.prototype.toString=function(){return "/I am not a duck^WRegExp/"};$$.prototype.source=$$.prototype.global=$$.prototype.ignoreCase=$$.prototype.multiline=$$.prototype.lastIndex="quack"; frog=new $$()
-
Paul Sweatte over 8 years@Tino That's why the
delete
keyword was used. If youdelete
them from an instance of aRegExp
object, you will get a different result than if you delete them from a custom object or any other built-in which is customized. See an unrelated question for further explanation. -
Nick Ribal over 7 years@TimDown, true, but
instanceof
won't work across execution contexts. -
Bergi almost 7 yearsIn contrast, anyone can construct an object whose
.constructor
has that name. -
Alexis Wilke over 5 yearsIn Node.js it returns
[object String]
so it's not helpful... Possibly because it's across contexts.