深拷贝正则表达式需用new RegExp(obj.source, obj.flags)显式构造,以完整保留模式和所有标志位;JSON方法和Object.assign无法复制其内部状态,而structuredClone()原生支持且自动处理。

JavaScript 中深拷贝正则表达式时,关键是要完整复制其 模式(source) 和 标志位(flags),否则新正则对象会丢失全局匹配(g)、忽略大小写(i)、多行模式(m)等行为。
正则表达式的标志位必须显式提取并重建
正则实例的 source 属性返回原始模式字符串,flags 属性返回所有启用的标志(如 "gi")。不能直接赋值或用 new RegExp(obj),因为后者只接受字符串参数,不识别原正则对象。
-
/abc/gim的.source是"abc",.flags是"gim" -
new RegExp(/abc/gim)❌ 错误:传入正则对象会被转成"[object RegExp]" -
new RegExp(/abc/gim.source, /abc/gim.flags)✅ 正确:分别提取再构造
在手写深拷贝函数中如何处理
检测到 obj instanceof RegExp 后,应使用 new RegExp(obj.source, obj.flags) 创建新实例。这是标准、安全且兼容所有标志的方式。
- 支持所有合法标志:
g、i、m、s(dotAll)、u(unicode)、y(sticky) - 无需手动拼接标志字符串,
obj.flags已按规范顺序返回(如"gimu") - 空标志(如
/abc/)时obj.flags为空字符串,new RegExp("abc", "")仍有效
为什么 JSON 方法和 Object.assign 不行
JSON.stringify() 会把正则转成空对象 {},Object.assign() 只复制可枚举属性,而 source 和 flags 是只读自有属性,但正则的内部状态无法通过简单遍历还原。
立即学习“Java免费学习笔记(深入)”;
-
JSON.parse(JSON.stringify({ r: /a/g }))→{ r: {} } -
Object.assign({}, /a/gi)→{}(无任何属性被复制) - 只有显式构造才能保留语义和行为
现代方案:structuredClone() 自动支持
ES2022 引入的 structuredClone() 原生方法已内置对正则的支持,能正确复制 source、flags 及 lastIndex(如果设置了 lastIndex)。
-
structuredClone(/hello\d+/gi)返回功能完全一致的新正则 - 无需手动判断类型,也不怕遗漏特殊对象
- 注意:目前不支持函数、undefined、window 等,但正则、Date、Map、Set、ArrayBuffer 等都涵盖


















