带有元素标记名的bug regexp?

时间:2015-06-08 15:53:28

标签: javascript regex tagname

简单的问题,有人可以向我解释一下吗?

http://jsfiddle.net/paj5c4wn/4/

// check body tagname, return bool
var check = (function ()
{
    var body = /body/gi;

    return function ( str )
    {

        return body.test( str );
    }

})();

// get body element
var body = document.body;

// display result
for ( var i = 0; i < 10; i++ )
{
    document.getElementById( 'result-' + i ).innerHTML = check( body.tagName );
}

with:

<p id="result-0" ></p>
<p id="result-1" ></p>
<p id="result-2" ></p>
...

做:

true

false

true

false

...

怎么可能?

1 个答案:

答案 0 :(得分:6)

有两种可能的解决方案:

  1. 您的代码始终使用与body变量相同的引用。结合正则表达式中的 g lobal标志,RegExp.prototype.test()记录并使用正则表达式匹配的最后一个索引开始搜索。

    首先,/body/gi在for循环的第一次迭代期间匹配'BODY',产生true。然后,在第二个函数调用中,它开始匹配索引4的字符串。因此,它从'BODY'字符串的末尾开始,因此它显然导致不匹配,返回false。然后索引在第三次测试时重置,因为字符串先前没有匹配,整个过程重复。

    要解决此问题,您可以删除闭包中的body变量,以允许在每个函数调用中创建一个新的正则表达式对象,每个函数调用的初始索引为0.

  2. 您只需删除 g lobal标志,因为此特定匹配只需要执行一次。如果没有g标志,JavaScript正则表达式对象将不会保留最后一个索引。相反,每次执行后索引将自动重置为零。

  3. 结合两个选项(因为在这种情况下,无论如何都不需要全局标志):

    // check body tagname, return bool
    var check = (function ()
    {
        return function ( str )
        {
    
            return /body/i.test( str );
        }
    
    })();
    
    // get body element
    var body = document.body;
    
    // display result
    for ( var i = 0; i < 10; i++ )
    {
        document.getElementById( 'result-' + i ).innerHTML = check( body.tagName );
    }