typeof for RegExp

49,178

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
Share:
49,178

Related videos on Youtube

tau
Author by

tau

Updated on January 28, 2022

Comments

  • tau
    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
      user113716 over 13 years
      See this answer to another question for concerns with the use of instanceof and constructor.
    • TOPKAT
      TOPKAT over 4 years
      Hi, 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
    tau over 13 years
    awesome. do you know which is faster/more compatible: using your instanceof method or the constructor.name method? thanks!
  • Cleiton
    Cleiton over 13 years
    instanceof, of course, you can verify it yourself using Firebug Timing(console.time)
  • Tim Down
    Tim Down over 13 years
    Those two code snippets are not identical. If you inserted the line t.constructor = function() {};, which is perfectly legal, then t instanceof RegExp will still be true but t.constructor == RegExp will be false. Using instanceof is therefore preferable.
  • Tim Down
    Tim Down over 13 years
    The constructor property can be changed. instanceof does not have this problem and is a better solution.
  • Tim Down
    Tim Down over 13 years
    Also, 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
    Tim Down over 13 years
    That'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
    Tim Down over 13 years
    They're duck typing here because typeof is unreliable for regexes and instanceof suffers from the cross-window problem. I wonder why they're not using @patrick dw's answer...
  • user113716
    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
    Tim Down over 13 years
    Unfortunately 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/thre‌​ad/… for a discussion of this.
  • Tim Down
    Tim Down over 13 years
    Now I know: it doesn't work in IE when examining objects from other windows.
  • Tim Down
    Tim Down over 13 years
    Apart from duck typing, which is irritatingly inexact, this is still the best answer.
  • user113716
    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
    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
    nickf almost 11 years
    Underscore now uses Object.prototype.toString.call(obj) == '[object RegExp]'
  • sebilasse
    sebilasse about 9 years
    Also, 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
    Tino over 8 years
    I do not understand your answer.
  • Tino
    Tino over 8 years
    sed -i s/native/primitive/. If you count object as primitive, typeof t only outputs the primitive type name (well. mostly. see developer.mozilla.org/de/docs/Web/JavaScript/Reference/…).
  • Paul Sweatte
    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 the source, global, ignoreCase, multiline, and lastIndex properties.
  • Tino
    Tino over 8 years
    Thanks, but unfortunately following frog proves that these characteristics are not unique to RegExps: $$=function(){};$$.prototype.toString=function(){return "/I am not a duck^WRegExp/"};$$.prototype.source=$$.prototype.global=$$.p‌​rototype.ignoreCase=‌​$$.prototype.multili‌​ne=$$.prototype.last‌​Index="quack"; frog=new $$()
  • Paul Sweatte
    Paul Sweatte over 8 years
    @Tino That's why the delete keyword was used. If you delete them from an instance of a RegExp 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
    Nick Ribal over 7 years
    @TimDown, true, but instanceof won't work across execution contexts.
  • Bergi
    Bergi almost 7 years
    In contrast, anyone can construct an object whose .constructor has that name.
  • Alexis Wilke
    Alexis Wilke over 5 years
    In Node.js it returns [object String] so it's not helpful... Possibly because it's across contexts.