现在,这里给出的答案并不完全正确/完整。
从ES5开始,字面量语法的行为与RegExp()
语法相同,关于对象创建:它们都会在代码路径命中它们所参与的表达式时创建一个新的RegExp对象。
因此,它们之间唯一的区别就是regexp被编译的频率:
- 使用字面量语法- 仅一次在初始代码解析和编译期间
- 使用
RegExp()
语法- 每次创建新对象时
例如,请参见Stoyan Stefanov's JavaScript Patterns书:
正则表达式字面量和构造函数之间的另一个区别是,字面量只在解析时创建对象一次。如果您在循环中创建相同的正则表达式,则将返回先前创建的对象,并且已经从第一次设置了所有属性(例如lastIndex)。请考虑以下示例,以说明两次返回相同对象的情况。
function getRE() {
var re = /[a-z]/;
re.foo = "bar";
return re;
}
var reg = getRE(),
re2 = getRE();
console.log(reg === re2);
reg.foo = "baz";
console.log(re2.foo);
此行为在ES5中已更改,文本也会创建新的对象。该行为已在许多浏览器环境中得到纠正,因此不能依赖它。
如果您在所有现代浏览器或NodeJS中运行此示例,则会得到以下内容:
false
bar
这意味着每次调用getRE()
函数时,即使是使用文字语法的方法,也会创建一个新的RegExp
对象。
上述不仅解释了为什么你不应该对不可变的正则表达式使用RegExp()
(这是今天非常明显的性能问题),还解释了:
(我更惊讶的是inlineRegExp和storedRegExp有不同的结果。)
由于没有创建(和垃圾回收)新的RegExp
对象的开销,所以在浏览器中,storedRegExp
比inlineRegExp
快5%到20%。
结论:
始终使用文字语法创建不可变的正则表达式,并且如果需要重新使用,请对其进行缓存。换句话说,在低于ES5的环境中不要依赖该行为差异,并在高于该环境的环境中继续适当进行缓存。
为什么使用文字语法?与构造函数语法相比,它具有一些优点:
- 它更短,不会强迫你按类似类的构造函数来思考。
- 当使用
RegExp()
构造函数时,还需要转义引号并双重转义反斜杠。这使得本质上就很难读懂和理解的正则表达式更加难以理解。
(摘自同一Stoyan Stefanov的JavaScript Patterns书籍)。
因此,除非你的正则表达式在编译时未知,否则始终使用文字语法是一个好主意。
RegExp
,因此 a) 必须查找该函数而不是直接评估它,b) 第二个可以在解析时进行评估,而第一个不能,因为调用RegExp
可能会产生副作用,如果您已经覆盖了它。 - pimvdb