【问题标题】:typeof for RegExp正则表达式的类型
【发布时间】:2011-05-19 08:46:17
【问题描述】:

是否有办法检测 JavaScript 对象是否为正则表达式?

例如,我想做这样的事情:

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

这可能吗?

谢谢!

编辑:感谢所有答案。看来我有两个很好的选择:

obj.constructor.name === "RegExp"

obj instanceof RegExp

这两种方法的主要优点/缺点?

再次感谢!

【问题讨论】:

  • 有关使用instanceofconstructor 的问题,请参阅this answer 到另一个问题。
  • 您好,我认为在您的问题中提供答案并不重要。如果您认为可以添加有用的内容,请考虑添加您自己的答案:)

标签: javascript regex constructor instanceof typeof


【解决方案1】:

您可以使用 instanceof 运算符:

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

其实也就是几乎一样:

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

请记住,由于 RegExp 不是 primitive data type,因此无法使用 typeof 运算符,而 be the best option 可以用于此问题。

但是你可以使用上面的这个技巧或者像duck type检查这样的技巧,例如,检查这样的对象是否有任何重要的方法或属性,或者通过它的内部类值 em>(通过使用{}.toString.call(instaceOfMyObject))。

【讨论】:

  • 太棒了。你知道哪个更快/更兼容:使用你的 instanceof 方法还是 constructor.name 方法?谢谢!
  • instanceof,当然你可以使用Firebug Timing(console.time)自己验证
  • 这两个代码 sn-ps 不相同。如果您插入了完全合法的行t.constructor = function() {};,那么t instanceof RegExp 仍然为真,但t.constructor == RegExp 为假。因此最好使用instanceof
  • 另外,t instanceof RegExp 从另一个窗口测试正则表达式对象时会报告错误,如果不需要这种检查,这不会有问题,但需要注意。
  • 此外,当在“if/else if”中使用并且您之前检查过 (typeof t === 'object') 时:将 -> && !(_t instanceof RegExp) 添加到此检查或如果可能,请先执行 Cleiton 的检查。 [tl;dr : 它也是 typeof 对象,如果在 "if/else if" 中使用就很重要...]
【解决方案2】:
alert( Object.prototype.toString.call( t ) ); // [object RegExp]

这是规范中提到的获取对象类的方式。

来自 ECMAScript 5,第 8.6.2 节对象内部属性和方法

[[Class]] 内部属性的值由本规范为每种内置对象定义。宿主对象的 [[Class]] 内部属性的值可以是任何字符串值,除了 “Arguments”、“Array”、“Boolean”、“Date”、“Error”、“Function”、 “JSON”、“数学”、“数字”、“对象”、“正则表达式”和“字符串”。 [[Class]] 内部属性的值在内部用于区分不同种类的对象。请注意,除了通过 Object.prototype.toString(参见 15.2.4.2)之外,本规范没有为程序提供任何访问该值的方法。

RegExp 是在 Section 15.10 RegExp(RegularExpression)Objects 的规范中定义的一类对象:

RegExp 对象包含一个正则表达式和相关的标志。

【讨论】:

  • @Tim - 我很确定。并不是说这是任何保证,而是method jQuery uses,包括RegExp。我将使用 RegExp 在 IE6 中进行快速测试,它确实有效(如果这是任何指标)。 :o) 似乎这种方法在第 3 版中被纳入规范。
  • 不幸的是,这在 IE 中对来自其他窗口的 RegExp 对象不起作用,原因与 [object Array] 检查不适用于数组的原因相同。有关演示,请参阅 jsfiddle.net/F6d8u,有关此问题的讨论,请参阅 groups.google.com/group/comp.lang.javascript/browse_frm/thread/…
  • 除了鸭子打字,这是令人恼火的不准确,这仍然是最好的答案。
  • @Tim - 有趣。当我有机会再次启动 IE 时,我将稍微仔细研究一下示例和文章。感谢您的意见。
  • 在 Node.js 中它返回 [object String] 所以它没有帮助......可能是因为它是跨上下文的。
【解决方案3】:

试一试.constructor 属性:

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

【讨论】:

  • constructor 属性可以更改。 instanceof没有这个问题,是更好的解决方案。
  • @TimDown,是的,但 instanceof 不能跨执行上下文工作。
  • 相反,任何人都可以构造一个.constructor具有该名称的对象。
【解决方案4】:

来自underscore.js

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

【讨论】:

  • 他们在这里打字是鸭子,因为typeof 对于正则表达式不可靠,而instanceof 存在跨窗口问题。我想知道他们为什么不使用@patrick dw 的答案...
  • 现在我知道了:从其他窗口检查对象时,它在 IE 中不起作用。
  • @Tim -- 太棒了......我想知道同样的事情,但还没有时间检查。感谢您在这里发布答案!
  • 下划线现在使用Object.prototype.toString.call(obj) == '[object RegExp]'
【解决方案5】:

在谷歌浏览器中工作:

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

【讨论】:

    【解决方案6】:

    “正则表达式”不是原生 Javascript 类型。上面的大多数答案告诉你如何完成你的任务,但没有告诉你为什么。这里是why

    【讨论】:

    • 这是一个误导性的答案。正则表达式绝对是原生 ECMAScript 和 JavaScript 对象。我认为你得到的是 typeof 的可能值不包括正则表达式的专用值。
    • sed -i s/native/primitive/。如果将object 算作原始类型,typeof t 只会输出原始类型名称(嗯。主要是。参见developer.mozilla.org/de/docs/Web/JavaScript/Reference/…)。
    【解决方案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 */
      

      如果字符串文字由正则表达式反斜杠分隔符分隔,则正则表达式自检将失败。

      如果Object.sealObject.freeze 在用户定义的对象上运行,并且该对象还具有上述所有属性,则delete 语句将返回误报。

      参考文献

      【讨论】:

      • 我不明白你的回答。
      • @Tino RegExp 类型有两个独特的特征。文字值以 / 字符开头和结尾。构造函数实例具有sourceglobalignoreCasemultilinelastIndex 属性。
      • 谢谢,但不幸的是,关注frog 证明这些特征对于RegExps 来说不是唯一的$$=function(){};$$.prototype.toString=function(){return "/I am not a duck^WRegExp/"};$$.prototype.source=$$.prototype.global=$$.prototype.ignoreCase=$$.prototype.multiline=$$.prototype.lastIndex="quack"; frog=new $$()
      • @Tino 这就是使用delete 关键字的原因。如果您从 RegExp 对象的实例中 delete 它们,您将获得与从自定义对象或任何其他自定义的内置对象中删除它们不同的结果。请参阅unrelated question 了解更多说明。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      • 2011-09-30
      相关资源
      最近更新 更多