Итак, в основном я написал себе эту функцию, чтобы иметь возможность подсчитывать количество вхождений подстроки в строку:
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 градусе по Фаренгейту» Рэя Брэдбери, ища все «s»).
Что меня беспокоит, так это невозможность изменить флаг предоставленного экземпляра RegExp. Нет смысла вызывать String.prototype.match в этой функции, если глобальный флаг предоставленного регулярного выражения не установлен в значение true, так как тогда будет учитываться только первое вхождение. Вы, безусловно, можете установить флаг вручную для каждого RegExp, переданного в функцию, однако я бы предпочел иметь возможность клонировать, а затем манипулировать предоставленными флагами регулярного выражения.
Удивительно, но мне не разрешено это делать, поскольку флаг RegExp.prototype.global (точнее, все флаги) доступен только для чтения. Отсюда закомментированная строка 8.
Итак, мой вопрос: Есть ли хороший способ изменить флаги объекта RegExp?
Я действительно не хочу делать такие вещи:
if(!expression.global)
expression = eval(expression.toString() + "g");
Некоторые реализации могут не поддерживать событие RegExp.prototype.toString и просто наследовать его от Object.prototype, или это может быть совершенно другое форматирование. И с самого начала это кажется плохой практикой кодирования.