使用正则/g引发的线上问题
问题出现
某个周末正吃着火锅唱着歌,接到了领导的电话。
“快看一下投放到xx客户端的页面,怎么没有头(导航栏)了?”
立即打开app查看发现果真只剩秃秃的页面直通手机顶部,便立即放心手中的碗筷跑回了家查看问题。
解决问题
由于是周末,解决问题的过程是相当痛苦的。很艰难的联系上了客户端同学,发现客户端和我们的h5页面近期都没有做过改动,问题的矛头便指向了adapter(客户端和h5通信的解决方案,公司内部支撑组封装使用)。这里涉及到复杂的业务不过多赘述,但是支撑组有改动过代码的正则方法,将/g全局匹配去掉便解决了。
大胆猜想
既然证实是正则匹配/g搞的鬼,那么究竟是如何导致问题出现的呢?
在细读代码时发现,由于业务逻辑复杂,某个初始化方法调用了两次正则,这让我怀疑是两次调用的问题,但仍然是一头雾水,但是别无他法,硬着头皮敲下了下面这段代码,结果让我大吃一惊
接下来就翻译翻译什么是惊喜
小心论证
我们先来看一段代码
const name = "jielun de yanzi"
const reg = /jielun/g
reg.test(name)
// true 第一次是true
reg.test(name)
// false 第二次是false
这不就对上了嘛。全局匹配两次,最终匹配的结果就是false!
问题开始有趣了,立马打开mdn去重新学习RegExp
这就是tama的惊喜。
简单说来,/g在全局匹配的同时,还会有一个lastIndex参数去记录下标,如果匹配成功了,便会去记录成功位置的下标,再次匹配时,从下标记录的位置开始,所以第二次便会出现返回false的情况,返回false之后,lastIndex置为0,第三次会是true 第四次是false 。。如此循环下去
加深下理解
const str = "aaab"
const reg = /a/g
reg.test(str)
// true 第一次匹配第一个“a”,是true,lastIndex置为1
reg.test(str)
// true 第二次匹配第二个“a”,是true,lastIndex置为2
reg.test(str)
// true 第三次匹配第三个“a”,是true,lastIndex置为3
reg.test(str)
// false 第四次匹配index为3的“b”,结果便是false,lastIndex置为0
reg.test(str)
// true 第五次便是true了
总结&反思
- 大胆猜想,小心论证的思路在大佬那里学到后屡试不爽。
- js太深奥了,接触的越多 越觉得自己是废柴。
- 重要逻辑在使用不熟悉api时,要熟读文档。
参考资料
转载自:https://juejin.cn/post/7141290987275419684