Chrome V8 Bug?函数在第二次调用后行为不同

11
请看下面的JavaScript代码。我从中删除了一些内容,让您可以专注于问题的关键。
您会注意到我连续两次调用prepPath函数,并传入完全相同的字符串。在Firefox和IE8中,这个函数每次都会弹出true(如预期)。但是,在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?


2
在正则表达式中,只有当您想要多次使用相同的表达式,并在使用之间标记lastIndex时,才需要使用“g”标志。如果没有“g”标志,则代码将按预期工作。如果在定义后设置regX.lastIndex = 0,它也将返回预期值。 - kennebec
1个回答

14

规范对于文字正则表达式何时应该重置存在一些模糊性(需要记住它们具有状态)。您可以通过执行以下操作来解决此问题:

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

实时演示:http://jsbin.com/irate

或者这个:

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

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

比我更深入研究此问题的人告诉我,这不是一个明显的bug,而是一种歧义。并且这不仅仅发生在Chrome上,其他浏览器的某些版本也有类似的问题。


那个可行了,谢谢。虽然有点不寻常。通常在函数中赋值之前使用“var”时,变量仍然是一个新的,只保留函数级别作用域,在调用之间没有状态。 - Lonnie Best
1
@LonnieBest:哦,这确实很不寻常,看起来肯定是错的,对吧?这与字面量及其何时被实例化有关,确实存在这样一个论点,即字面量被实例化一次,然后被重复使用,尽管看起来很奇怪。如果这能让你稍微安慰一下的话,这是我所知道的这种奇怪行为的唯一例子。 :-) - T.J. Crowder
1
这实际上是规范要求的行为:http://bclary.com/2004/11/07/#a-7.8.5。关于此问题,有一个Chromium错误报告:http://code.google.com/p/chromium/issues/detail?id=2161。 - lawnsea
如果我想让RegEx对象保持状态,我应该在函数之外声明它。尽管规范不明确,但我认为Chromium v8团队应该与Firefox和IE保持一致。 - Lonnie Best
1
@LonnieBest:两点都同意。由于在第五版规范定稿之前就已知道这一点,我有点希望新规范能够澄清它,但我还没有深入研究过。 - T.J. Crowder
@T.J.Crowder:我知道这个名字听起来很熟悉;我刚在亚马逊上看到了你的,并且已经预订了。 - Lonnie Best

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接