Строки неизменны в JavaScript, поэтому такие вещи, как это не будет работать
// can't reassign `this` in String.prototype method !
this = this.replace(f,r)
Вместо этого, вы должны вернуть новую строку из вашей функции
String.prototype.replaceAll = function replaceAll(f,r) {
if (this.indexOf(f) === -1)
return this.toString()
else
return this.replace(f, r).replaceAll(f,r)
}
console.log('foobar foobar'.replaceAll('foo', 'hello')) // => 'hellobar hellobar'
console.log('foobar foobar'.replaceAll('o', 'x')) // => 'fxxbar fxxbar'
Итак, это короткий ответ, если вы не возражаете, полагаясь на встроенные функции, такие как String.prototype.indexOf
и String.prototype.replace
Если вы хотите реализовать их с нуля, вы можете сделать это с помощью очень простого JavaScript. Вам не нужно использовать цикл while
. Вы можете, но заявление вроде & hellip;
Поэтому мне действительно нужно использовать первую функцию с циклом while.
& hellip; false.
Начнем с базовой функции find
. Это работает как String.prototype.indexOf
function find(s, x) {
function loop(s, pos) {
if (s.substring(0, x.length) === x)
return pos
else if (s === '')
return -1
else
return loop(s.substring(1), pos + 1)
}
return loop(s, 0)
}
console.log(find('foobar', 'f')) // => 0
console.log(find('foobar', 'bar')) // => 3
console.log(find('foobar', 'x')) // => -1
console.log(find('foobar', '')) // => 0
Тогда А replace
функция, которая работает, чтобы заменить один экземпляр x
с y
в строке s
function replace(s, x, y, idx) {
// idx is an optional parameter here for optimizing replaceAll
// you'll see it used in the next example
if (idx === undefined)
return replace(s, x, y, find(s, x))
else if (idx === -1)
return s
else
return s.substring(0, idx) + y + s.substring(idx + x.length)
}
console.log(replace('foobar', 'foo', 'hello')) // => 'hellobar'
console.log(replace('foobar', 'bar', 'hello')) // => 'foohello'
Затем, внедрение replaceAll
является простой рекурсивной функции
function replaceAll(s, x, y) {
var idx = find(s, x)
if (idx === -1)
return s
else
// use 4th parameter in replace function so index isn't recalculated
return replaceAll(replace(s, x, y, idx), x, y)
}
console.log(replaceAll('foobar foobar', 'foo', 'hello')) // => 'hellobar hellobar'
console.log(replaceAll('foobar foobar', 'o', 'x') ) // => 'fxxbar fxxbar'
Вы можете реализовать все эти функции на String.prototype
, если хотите, так что бы работали такие вещи, как 'foobar'.replaceAll('o', 'x')
.
Если вам не нравится find
, вы можете использовать инструкцию String.prototype.indexOf
.С другой стороны, если вы делаете это как упражнение, и вы пытаетесь реализовать все это с нуля, вы даже можете зайти так далеко, чтобы не полагаться на String.prototype.substring
, который я использовал здесь.
Кроме того, для чего это стоит, здесь ваш код работает отлично
String.prototype.replaceAll = function(f,r) {
return this.split(f).join(r);
};
'foobar foobar'.replaceAll('foo', 'hello')
// => "hellobar hellobar"
'foobar foobar'.split('foo').join('hello')
// => "hellobar hellobar"
хорошо вы вроде обмана, используя 'String.prototype.replace' в реализации. Но вы знаете, что можете использовать 'string.replace (/ find/g, 'replacement')', если вы хотите заменить все, правильно? – naomik
Танк вам за ответ! Я знаю, что я могу использовать/g и/gi. На самом деле, мой код уже работает с помощью replace/g. Но в какой-то момент я захотел использовать небольшую функцию, чтобы использовать RegExp. Но, как мы видели, без причины, цикл while не работал. – Yan
Я предоставил гораздо более подробный ответ ниже – naomik