大前端与勇士

打工人带你一起刷大前端副本 111

【要命的神奇bug】if条件 使用 正则表达式

今天在做一个输入判断,使用了正则,因为多处会用到,所以用了一个全局变量来接收,这也没问题
然后,出现了一个神奇的事情,我输出正则表达式的结果为false,但是if的判断却走了true???? WTF????

代码大致如下

    // 判断密码正则
    const passwordPatern = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\!\@\#\$\%\^\*\(\)])[a-zA-Z0-9\!\@\#\$\%\^\*\(\)]{8,17}$/g

    // 判断密码
    let tm
    esui.get('password').on('input', function () {
        clearTimeout(tm)
        // 节流
        tm = setTimeout(() => {
            console.log(this.getValue(), passwordPatern.test(this.getValue()))
            if (passwordPatern.test(this.getValue())) {
                console.log('1')
            }
            else {
                console.log('密码不符合要求')
            }

        }, 800);
    })

密码符合要求应该会输出1
测试结果却出人意料,console明明输出了true,密码符合要求,却走了else,WTF!!! 这就令人匪夷所思了
结果

难道if的判断有bug?经过多次试验测试,if(false)肯定不会执行,使用一个变量接收正则判断的结果后,也不会出现那个问题

所以,这应该是正则表达式的问题

那么,正则表达式有什么问题呢,经过进一步测试,passwordPatern.test('q123456!')的结果不是固定的,一会儿为true,一会儿为false
正则判断结果跳动
我知道鼠标放上去会执行一次js获取结果,所以大胆的想一想,这个正则的执行结果会变,但是又觉得不科学啊
又写了一个简单的测试用例

const exp = /abc/g

console.log(exp.test('abc'))
console.log(exp.test('abc'))
console.log(exp.test('abc'))

这个会输出3个true吗?
输出结果

为什么会输出false呢?这就是正则的一个特性了(坑坑坑)
去搜索了一圈,在MDN的网站上,找到这么一句:

test called multiple times on the same global regular expression instance will advance past the previous match.

因为例子中的正则带了g,所以每次调用test方法会先获取一个隐藏属性lastIndex,会跳过上次已经搜索过的部分。

第偶数次调用test的时候,就从前一次的lastIndex开始搜索。结果搜不到,就返回false。lastIndex置为0,下一次调用时,就又能搜到了。

posted on 2020-12-15 16:22  秦伟杰  阅读(354)  评论(0编辑  收藏  举报

导航