Regex error with element tag?

Simple question, can anyone explain this to me?

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 );
}

      

from:

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

      

do:

true

false

true

false

...

      

how is it possible?

+3


source to share


1 answer


There are two possible solutions:

  • Your code always uses the same variable reference body

    . Combined with the g flag in a regular expression, RegExp.prototype.test()

    writes and uses the last index that matches the regular expression to start the search.

    First, it /body/gi

    matches 'BODY'

    during the first iteration of the for loop, giving true

    . Then, in the second call to the function, it starts matching the string at index 4. So it starts at the end of the string 'BODY'

    , so it obviously doesn't match, returning false

    . The index is then reset in the third test, since the string did not match earlier and the whole process repeats.

    To counteract this, you can remove the variable body

    in the closure to allow a new regex object to be created with each function call, each with a starting index of 0.

  • You can simply remove the g lobal flag as this particular match only needs to be executed once. Without the flag, the g

    JavaScript regex object will not store the last index. Instead, the index will automatically be reset to zero after each execution.



Combining both options (since the global flag is not needed in this case):

// 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 );
}

      

+6


source







All Articles