Typeof для RegExp

Есть ли способ определить, является ли объект JavaScript регулярным выражением?

Например, я хотел бы сделать что-то вроде этого:

var t = /^foo(bar)?$/i;
alert(typeof t); //I want this to return "regexp"

Возможно ли это?

Спасибо!

EDIT: Спасибо за все ответы. Кажется, у меня есть два очень хороших варианта:

obj.constructor.name === "RegExp"

или

obj instanceof RegExp

Любые основные плюсы/минусы для любого метода?

Еще раз спасибо!

Ответ 1

Вы можете использовать оператор instanceof:

var t = /^foo(bar)?$/i;
alert(t instanceof RegExp);//returns true

Фактически, это почти то же самое, что:

var t = /^foo(bar)?$/i;
alert(t.constructor == RegExp);//returns true

Имейте в виду, что поскольку Regex не является примитивным типом данных, невозможно использовать typeof, который мог бы быть лучшим вариантом для этого вопроса.

Но вы можете использовать этот трюк выше или другие, такие как тип утки, проверяя, например, проверку, есть ли у такого объекта какие-либо жизненные методы или свойства или его внутренний класс значение (используя {}.toString.call(instaceOfMyObject)).

Ответ 2

alert( Object.prototype.toString.call( t ) ); // [object RegExp]

Это способ, упомянутый в спецификации для получения класса объекта.

От ECMAScript 5, раздел 8.6.2 Внутренние свойства и методы объекта:

Значение внутреннего свойства [[Class]] определяется этой спецификацией для каждого типа встроенного объекта. Значение внутреннего свойства [[Class]] для объекта-хозяина может быть любым значением String, за исключением одного из "Аргументов", "Массив", "Логическое", "Дата", "Ошибка", "Функция", "JSON", "Math", "Number", "Object", "RegExp" и "String" . Значение внутреннего свойства [[Class]] используется внутри, чтобы различать различные типы объектов. Обратите внимание, что эта спецификация не предоставляет никаких средств для доступа к этому значению для программы, кроме как через Object.prototype.toString(см. 15.2.4.2).

RegExp - это класс объекта, определенный в спецификации в Раздел 15.10 Объекты RegExp (RegularExpression):

Объект RegExp содержит регулярное выражение и связанные с ним флаги.

Ответ 3

Дайте свойству .constructor вихрь:

> /^foo(bar)?$/i.constructor
function RegExp() { [native code] }
> /^foo(bar)?$/i.constructor.name
"RegExp"
> /^foo(bar)?$/i.constructor == RegExp
true

Ответ 4

От underscore.js

// Is the given value a regular expression?
  _.isRegExp = function(obj) {
    return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
  };

Ответ 5

Работает в google chrome:

x = /^foo(bar)?$/i;
x == RegExp(x); // true
y = "hello";
y == RegExp(y); // false

Ответ 6

"Regexp" не является родным Javascript-типом. Большинство вышеперечисленных ответов говорят вам, как выполнить свою задачу, но не почему. Здесь почему.

Ответ 7

Нет абсолютного способа проверить это, пока лучший ответ

var t = /^foo(bar)?$/i;
alert(t instanceof RegExp);//returns true

но есть одна нижняя сторона этого подхода и что он вернет false, если объект регулярного выражения отправляется из другого окна.

Ответ 8

Вот два способа:

/^\/.*\/$/.test(/hi/) /* test regexp literal via regexp literal */
/^\/.*\/$/.test(RegExp("hi") ) /* test RegExp constructor via regexp literal */
RegExp("^/" + ".*" + "/$").test(/hi/) /* test regexp literal via RegExp constructor */
RegExp("^/" + ".*" + "/$").test(RegExp("hi") ) /* test RegExp constructor via RegExp constructor */ 

delete RegExp("hi").source /* test via deletion of the source property */
delete /hi/.global /* test via deletion of the global property */
delete /hi/.ignoreCase /* test via deletion of the ignoreCase property */
delete RegExp("hi").multiline /* test via deletion of the multiline property */
delete RegExp("hi").lastIndex /* test via deletion of the lastIndex property */

Если строковый литерал ограничивается разделителем обратного слэжа regexp, самотестирование регулярного выражения не будет выполнено.

Если Object.seal или Object.freeze выполняются на определяемом пользователем объекте, и этот объект также имеет все вышеупомянутые свойства, оператор delete возвращает ложное положительное значение.

Ссылки