最近帮同事查一个问题,他写了个简单的脚本想把日志里的敏感信息替换掉,结果发现ref="/tag/255/" style="color:#479099;font-weight:bold;">字符串的 replace 方法压根没起作用。代码看着没问题,但运行后原字符串还是老样子,一点没变。
原地修改?别被错觉骗了
他写的代码大概是这样的:
let log = "[ERROR] 用户密码错误:123456";
log.replace("123456", "******");
console.log(log);
输出结果还是带明文密码的原始内容。问题出在 replace 并不会修改原字符串,而是返回一个新字符串。JavaScript 中字符串是不可变类型,所有操作都不会改变自身。
记得接住返回值
正确的做法是把 replace 的结果重新赋值:
let log = "[ERROR] 用户密码错误:123456";
log = log.replace("123456", "******");
console.log(log); // [ERROR] 用户密码错误:******
这个细节很容易忽略,特别是刚从 Python 或其他语言转过来的人,总觉得“改了就改了”,其实 JS 得你明确说“我要用新值”。
正则匹配也要小心
还有一次我处理监控日志时想批量替换 IP 地址,用了正则但没加全局标志:
const text = "访问来自 192.168.1.1 和 192.168.1.1";
text.replace(/192\.168\.1\.1/, "[HIDDEN]");
结果只替换了第一个,第二个还在。得加上 g 标志才行:
text = text.replace(/192\.168\.1\.1/g, "[HIDDEN]");
大小写敏感问题也常见
有个运维小哥反馈说日志里的 “error” 没被替换,一看才发现有的写成 “Error” 或 “ERROR”。默认 replace 是区分大小写的。如果想一并处理,可以用正则加 i 标志:
log = log.replace(/error/gi, "[ALERT]");
这种问题在做网络异常监控时特别容易踩坑,尤其是日志来源复杂的时候。
别忘了检查数据类型
有次我折腾半天 replace 不生效,最后发现那个“字符串”其实是 null 或 undefined。还有的是从接口拿的数据,看着像字符串,其实是数字类型,比如状态码 500 写成 number 而不是 '500'。这种当然没法用 replace。
简单加个 toString() 或前置转换就能避免:
const code = 500;
const msg = "服务异常:" + code;
msg.replace(code.toString(), "***");
遇到 replace 不生效,先打印一下变量类型和值,很多时候问题就清楚了。