为RegExp键入

无论如何检测一个JavaScript对象是否是一个正则expression式?

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

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

这可能吗?

谢谢!

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

 obj.constructor.name === "RegExp" 

要么

 obj instanceof RegExp 

任何方法的主要优点/缺点?

再次感谢!

你可以使用instanceof操作符:

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

实际上,这几乎是一样的:

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

请记住,由于正则expression式不是原始数据types ,因此不可能使用typeof运算符,这可能是此问题的最佳select 。

但是你可以使用上面的这个技巧或者其他类似鸭子检查的方法 ,比如检查这个对象是否有重要的方法或者属性,或者通过内部类的值 (通过使用{}.toString.call(instaceOfMyObject) )。

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

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

ECMAScript 5的8.6.2节对象内部属性和方法

本规范针对每种内置对象定义了[[Class]]内部属性的值。 主对象的[[Class]]内部属性的值可以是“Arguments”,“Array”,“Boolean”,“Date”,“Error”,“Function”,“JSON” ,“math”,“数字”,“对象”,“RegExp”和“string” 。 [[Class]]内部属性的值用于内部区分不同types的对象。 请注意,除了通过Object.prototype.toString(见15.2.4.2)外,本规范没有提供任何方法让程序访问该值。

RegExp是第15.10节规范中定义的一类对象RegExp(RegularExpression)对象

RegExp对象包含正则expression式和关联的标志。

.constructor属性一个旋风:

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

来自underscore.js

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

在谷歌浏览器工作:

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

“正则expression式”不是原生的Javascripttypes。 上面的大部分答案告诉你如何完成你的任务,但不是为什么。 这是为什么 。

没有绝对的方法来检查这个,到目前为止最好的答案是

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

但是这种方法存在一个缺陷,那就是如果正则expression式对象正在从另一个窗口中读取,它将返回false。

这里有两种方法:

 /^\/.*\/$/.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 */ 

如果string文字由正则expression式反斜线分隔符分隔,则正则expression式自检将失败。

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

参考

  • ECMAScript 5,第15.10.4.1节新的RegExp(模式,标志)

  • 什么是delete在JavaScript中非常有用的一些用例?

  • 为什么这个可configuration属性不可删除?

  • Webkit JavaScriptCore源代码:ObjectConstructor.cpp

  • JavaScript中的对象属性