Ошибка регулярного выражения с тэгом элемента?
Простой вопрос, кто-нибудь может мне это объяснить?
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 ответ
Есть два возможных решения:
Ваш код всегда использует одну и ту же ссылку на
body
переменная. В сочетании с флагом g lobal в регулярном выраженииRegExp.prototype.test()
записывает и использует последний индекс, с которым сопоставлено регулярное выражение, чтобы начать поиск.Первый,
/body/gi
Матчи'BODY'
во время первой итерации цикла for, получаяtrue
, Затем при втором вызове функции начинается сопоставление строки из индекса 4. Таким образом, она начинается в конце'BODY'
строка, поэтому она явно не соответствует, возвращаяfalse
, Индекс затем сбрасывается в третьем тесте, так как строка ранее не совпадала, и весь процесс повторяется.Чтобы противодействовать этому, вы можете удалить
body
переменная в замыкании, позволяющая создавать новый объект регулярного выражения при каждом вызове функции, каждый с начальным индексом 0.Вы можете просто убрать флаг 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 );
}