regexp对象创建有字面量和构造函数两种方式:前者编译时确定、高效稳定,适合静态模式;后者运行时解析、灵活可变,适合动态生成。

创建 RegExp 对象的关键在于理解两种方式的本质差异:字面量是编译时确定、高效稳定;构造函数是运行时解析、灵活可变。选哪种,取决于你的模式是否固定。
字面量方式:简洁、高效、适合静态模式
用一对斜杠包裹模式和修饰符,例如 /d{3}-d{4}/i。JavaScript 引擎在代码解析阶段就完成编译,后续重复使用不会重新编译——这对循环中频繁调用的正则尤其重要。
- 修饰符直接跟在末尾斜杠后,如
/abc/gi表示全局 + 忽略大小写 - 特殊字符无需额外转义(除斜杠本身),
/a.b/中的点就是元字符,匹配任意单字符 - 不能拼接变量,模式必须在写代码时就明确
构造函数方式:动态、可控、适合运行时生成
用 new RegExp(pattern, flags) 创建,第一个参数是字符串,第二个是修饰符字符串(如 'gi')。因为 pattern 是字符串,所有反斜杠都要双写,比如要匹配一个反斜杠,得写成 "\";要匹配 w+,就得写 "w+"。
- 适用于从用户输入、配置项或 API 响应中获取正则模式的场景
- 每次调用都会触发一次正则编译,性能略低,但换来的是灵活性
- 可安全组合变量:
const key = 'email'; new RegExp(`${key}@\w+\.com`, 'i')
编译时机与实际影响
字面量在脚本加载或函数定义时编译一次;构造函数在执行到那行代码时才编译。这意味着:
- 带
g修饰符的字面量在多次test()或exec()调用中会维护lastIndex状态,可能影响结果顺序 - 构造函数创建的对象每次都是全新实例,
lastIndex初始为 0,状态不跨调用保留 - 若正则模式不变,优先用字面量——更易读、更快、更安全
验证你是否编译正确的小技巧
打印 regex.source 可看到原始模式字符串,regex.flags 返回当前所有修饰符,regex.toString() 会还原成 /pattern/flags 形式。遇到匹配异常时,先检查 source 是否符合预期,再确认转义是否到位。











