问题 Chrome V8 Bug?功能在第二次调用后表现不同


请查看以下JavaScript。我已经把它拿走了,所以你可以专注于问题的本质。

您会注意到我连续两次调用prepPath函数,传入完全相同的字符串。在firefox和IE8中,此函数每次都会发出警告(如预期的那样)。但是,在Chromium 5.0.375.127(55887)Ubuntu 10.04中,该函数第一次返回true,而假第二次调用为false,尽管输入保持完全相同!

<script type="text/javascript"> 
    function prepPath(str)
    {   
        var regX = /[^\s/"'\\].*[^\s/"'\\]/g;
        if(regX.test(str))
        {
            alert("true: " + str);
        }
        else
        {
            alert("false; " + str);
        }
    }

    prepPath("/desktop"); // alerts: true
    prepPath("/desktop"); // alerts: false 
</script> 

为什么它在Chromium中第二次返回false?


10546
2017-09-13 18:00


起源

唯一一次在常规表达中需要'g'标志的情况是,如果要多次使用相同的表达式,则在使用之间标记lastIndex。如果没有'g'标志,您的代码就会以您期望的方式运行。如果在定义后设置regX.lastIndex = 0,它也将返回预期值。 - kennebec


答案:


关于何时应该重置字面正则表达式的规范存在一些模糊性(回想一下它们是否具有状态)。你可以通过这样做来解决这个问题:

var regX = new RegExp(/[^\s/"'\\].*[^\s/"'\\]/g);

实例: http://jsbin.com/irate

或这个:

var regX = /[^\s/"'\\].*[^\s/"'\\]/g;
regX.lastIndex = 0;

实例: http://jsbin.com/irate/2

我得知那些比我更了解它的人,它实际上并不是一个彻头彻尾的错误,而是一种含糊不清的错误。而且它不只是Chrome,其他浏览器的某些版本也有类似的问题。


14
2017-09-13 18:02



这有效;谢谢。但不寻常。通常,在设置变量值(在函数中)之前使用“var”时,无论如何变量都是新变量,并且只保持函数级别范围,调用之间的状态为零。 - Lonnie Best
@LonnieBest:哦,这是不寻常的,它肯定看起来不对,不是吗?它与文字有关,当它们被实例化时,确实存在一个论证,即文字被实例化 一旦 然后重复使用,虽然看起来很奇怪。这是我所知道的这种奇怪行为的唯一例子,如果这是任何安慰。 :-) - T.J. Crowder
它实际上是需要此行为的规范: bclary.com/2004/11/07/#a-7.8.5。关于它有一个Chromium错误: code.google.com/p/chromium/issues/detail?id=2161。 - lawnsea
如果我希望RegEx对象保持状态,我会在函数之外声明它。尽管规范含糊不清,我认为Chromium v​​8团队应该在这个版本上与firefox和IE同步。 - Lonnie Best
@LonnieBest:同意这两个方面。由于这是在第5版规范最终确定之前就已知的,我希望新的规范能够澄清它,但我没有深入到这个深度。 - T.J. Crowder