常见写法
e = JSON.parse(
JSON.stringify(e).replace(
/https:\/\/old-domain\.obs\.cn-east-4\.example\.com:443/g,
'/api'
)
);
先序列化为 JSON 字符串,全局替换目标子串,再反序列化回对象。适合简单的 URL 替换场景。
用 replaceAll 替代正则
对字面字符串使用正则容易漏掉 . 的转义(.com 写成 .com 会匹配任意字符),直接用 replaceAll 更安全:
const target = 'https://old-domain.obs.cn-east-4.example.com:443';
e = JSON.parse(
JSON.stringify(e).replaceAll(target, '/api')
);
replaceAll 是纯字符串匹配,不会误伤相邻字符,可读性也更强。
JSON.stringify 会丢失特殊值
// 以下类型经 JSON.stringify 后会丢失或变形
new Date() // 变为 ISO 字符串,失去 Date 类型
new Map() // 变为 {}
new Set() // 变为 {}
undefined // 对象属性被整体删除
BigInt // 抛出 TypeError
function // 被删除
如果对象中包含这些类型,序列化 + 替换 + 反序列化会静默丢失数据。
推荐:递归遍历替换
function deepReplace(obj, from, to) {
if (typeof obj === 'string') {
return obj.replaceAll(from, to);
}
if (Array.isArray(obj)) {
return obj.map(v => deepReplace(v, from, to));
}
if (obj && typeof obj === 'object') {
for (const k in obj) {
obj[k] = deepReplace(obj[k], from, to);
}
}
return obj;
}
deepReplace(e, 'https://old-domain.com', '/api');
不走序列化路径,Date / Map / Set / 原型链全部保留,也适合在 hook 网络返回数据时做在线 URL 替换。
适用场景对比
| 场景 | 推荐方式 |
|---|---|
| 简单纯字符串对象 | JSON.parse(JSON.stringify(e).replaceAll(...)) |
| 含 Date / Map / Set 的对象 | deepReplace() 递归遍历 |
| 只替换字面字符串(无转义歧义) | replaceAll 替代正则 |
| hook 网络数据在线修改 | deepReplace() |
