const re = /^1[3-9]\d{9}$/; // 不要加 g
re.test('13800138000');
// 带 g 时先归零
re.lastIndex = 0;
同一个手机号校验函数,第一次返回 true,用户改了一个字符再输回来,第二次变成 false,第三次又对了。控制台里那个正则对象是全局共用的。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,带 g 或 y 标志的正则会在 lastIndex 上记住上次匹配结束的位置,下一次 test 从那里继续找。表单校验只关心有没有匹配,这个状态没有意义,却让结果一次对一次错。
「正则 lastIndex」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改完隔一天再看一次,当场正常不代表能稳住。
测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
处理上按这个顺序:校验用的正则去掉 g 和 y 标志,只保留需要的 i;确实要复用带 g 的正则时,每次 test 前把 lastIndex 手动归零;把正则写进函数内部每次新建,别在模块顶层共享实例。
改完只确认一件事:同一个号码连续校验十次结果都是 true,输入非法号码时稳定返回 false。
