为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.seal
或Object.freeze
在用户定义的对象上运行,并且该对象也具有上述所有属性,则delete
语句将返回误报。
参考
-
ECMAScript 5,第15.10.4.1节新的RegExp(模式,标志)
-
什么是
delete
在JavaScript中非常有用的一些用例? -
为什么这个可configuration属性不可删除?
-
Webkit JavaScriptCore源代码:ObjectConstructor.cpp
-
JavaScript中的对象属性