Ошибка регулярного выражения с тэгом элемента?

Простой вопрос, кто-нибудь может мне это объяснить?

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

с:

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

делать:

true

false

true

false

...

как это возможно?

1 ответ

Решение

Есть два возможных решения:

  1. Ваш код всегда использует одну и ту же ссылку на body переменная. В сочетании с флагом g lobal в регулярном выражении RegExp.prototype.test() записывает и использует последний индекс, с которым сопоставлено регулярное выражение, чтобы начать поиск.

    Первый, /body/gi Матчи 'BODY' во время первой итерации цикла for, получая true, Затем при втором вызове функции начинается сопоставление строки из индекса 4. Таким образом, она начинается в конце 'BODY' строка, поэтому она явно не соответствует, возвращая false, Индекс затем сбрасывается в третьем тесте, так как строка ранее не совпадала, и весь процесс повторяется.

    Чтобы противодействовать этому, вы можете удалить body переменная в замыкании, позволяющая создавать новый объект регулярного выражения при каждом вызове функции, каждый с начальным индексом 0.

  2. Вы можете просто убрать флаг g lobal, поскольку это конкретное совпадение нужно выполнить только один раз. Без g флаг, объект регулярного выражения JavaScript не сохранит последний индекс. Вместо этого индекс будет автоматически обнуляться после каждого выполнения.

Объединение обоих вариантов (поскольку в этом случае глобальный флаг не нужен):

// 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 );
}
Другие вопросы по тегам