Итак, я написал эту функцию, чтобы подсчитать количество вхождений подстроки в строке:
String.prototype.numberOf = function(needle) {
var num = 0,
lastIndex = 0;
if(typeof needle === "string" || needle instanceof String) {
while((lastIndex = this.indexOf(needle, lastIndex) + 1) > 0)
{num++;} return num;
} else if(needle instanceof RegExp) {
// needle.global = true;
return this.match(needle).length;
} return 0;
};
Сам метод работает довольно хорошо, и оба поиска на основе RegExp и String вполне сопоставимы по времени выполнения (оба ~ 2 мс на всем «451 по Фаренгейту» Рэя Брэдбери, ищущего все «the»). 1004 *
Что меня беспокоит, так это невозможность изменить флаг предоставленного экземпляра RegExp. Нет смысла вызывать String.prototype.match в этой функции без глобального флага поставляемого регулярного выражения, установленного в значение true, так как он будет отмечать только первое вхождение. Конечно, вы можете установить флаг вручную для каждого передаваемого в функцию RegExp, однако я бы предпочел иметь возможность клонировать и затем манипулировать флагами поставляемого регулярного выражения.
Удивительно, но мне запрещено это делать, поскольку флаг RegExp.prototype.global (точнее, все флаги) доступен только для чтения. Отсюда закомментированная строка 8.
Итак, мой вопрос: Есть ли хороший способ изменения флагов объекта RegExp?
Я действительно не хочу делать такие вещи:
if(!expression.global)
expression = eval(expression.toString() + "g");
Некоторые реализации могут не поддерживать событие RegExp.prototype.toString и просто наследовать его от Object.prototype , или это может быть совсем другое форматирование. И это просто кажется плохой практикой кодирования.