Natürlich in 2021 ist die richtige Antwort:
console.log(
'Change this and this for me'.replaceAll('this','that') // Normal case
);
console.log(
'aaaaaa'.replaceAll('aa','a') // Challenged case
);
Wenn Sie keine Lust haben, sich mit ersetzen() + RegExp .
Was aber, wenn der Browser <2020 ist?
In diesem Fall benötigen wir Polyfill (Zwingt ältere Browser, neue Funktionen zu unterstützen) (Ich denke, für ein paar Jahre notwendig sein)
Ich konnte keine völlig richtige Methode in den Antworten finden. Daher schlage ich diese Funktion vor, die als Polyfill definiert werden soll.
Meine vorgeschlagenen Optionen für replaceAll
Polyfill:
replaceAll
polyfill (Mit global-flag Fehler) [Prinzipiellere Version]
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
return this.replace( // Using native String.prototype.replace()
Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
? search.global // Is the RegEx global?
? search // So pass it
: function(){throw new TypeError('replaceAll called with a non-global RegExp argument')}() // If not throw an error
: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
replace); // passing second argument
}
});
}
replaceAll
Polyfill (mit der Handhabung des fehlenden Global-Flags selbst) [Meine erste Präferenz] - Warum?
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
return this.replace( // Using native String.prototype.replace()
Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
? search.global // Is the RegEx global?
? search // So pass it
: RegExp(search.source, /\/([a-z]*)$/.exec(search.toString())[1] + 'g') // If not, make a global clone from the RegEx
: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
replace); // passing second argument
}
});
}
Minified [Meine erste Präferenz]:
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
Versuchen Sie es:
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
console.log(
'Change this and this for me'.replaceAll('this','that')
); // Change that and that for me
console.log(
'aaaaaa'.replaceAll('aa','a')
); // aaa
console.log(
'{} (*) (*) (RegEx) (*) (\*) (\\*) [reserved characters]'.replaceAll('(*)','X')
); // {} X X (RegEx) X X (\*) [reserved characters]
console.log(
'How (replace) (XX) with $1?'.replaceAll(/(xx)/gi,'$$1')
); // How (replace) ($1) with $1?
console.log(
'Here is some numbers 1234567890 1000000 123123.'.replaceAll(/\d+/g,'***')
); // Here is some numbers *** *** *** and need to be replaced.
console.log(
'Remove numbers under 233: 236 229 711 200 5'.replaceAll(/\d+/g, function(m) {
return parseFloat(m) < 233 ? '' : m
})
); // Remove numbers under 233: 236 711
console.log(
'null'.replaceAll(null,'x')
); // x
// The difference between My first preference and the original:
// Now in 2022 with browsers > 2020 it should throw an error (But possible it be changed in future)
// console.log(
// 'xyz ABC abc ABC abc xyz'.replaceAll(/abc/i,'')
// );
// Browsers < 2020:
// xyz xyz
// Browsers > 2020
// TypeError: String.prototype.replaceAll called with a non-global RegExp
Browser-Unterstützung:
IE 9+ (Getestet mit IE11)
Alle anderen Browser (nach 2012)
Das Ergebnis ist dasselbe wie das native replaceAll im Falle des ersten Arguments Eingabe sein:
null
, undefined
, Object
, Function
, Date
, ... , RegExp
, Number
, String
, ...
Ref: https://tc39.es/ecma262/#sec-string.prototype.replaceall _+ RegExp-Syntax_
Wichtiger Hinweis: Wie von einigen Fachleuten erwähnt, liefern viele der rekursiven Funktionen, die in den Antworten vorgeschlagen werden, ein falsches Ergebnis. (Probieren Sie sie mit dem herausgeforderten Fall des obigen Ausschnitts aus)
Vielleicht einige knifflige Methoden wie .split('searchValue').join('replaceValue')
oder Einige gut verwaltete Funktionen liefern das gleiche Ergebnis, aber definitiv viel weniger Leistung als native replaceAll()
/ polyfill replaceAll()
/ replace() + RegExp
Andere Methoden der Polyfill-Zuweisung
Naiv, aber unterstützt auch Ältere (besser zu vermeiden)
Wir können zum Beispiel auch IE7+ unterstützen, indem wir nicht Object.defineProperty() und meine alte naive Zuweisungsmethode anwenden:
if (!String.prototype.replaceAll) {
String.prototype.replaceAll = function(search, replace) { // <-- Naive method for assignment
// ... (Polyfill code Here)
}
}
Und es sollte für grundlegende Anwendungen im IE7+ gut funktionieren.
Aber als aquí @sebastian-simon erläuterte, die bei weitergehenden Anwendungen zu sekundären Problemen führen können. Z.B.:
for (var k in 'hi') console.log(k);
// 0
// 1
// replaceAll <-- ?
Vollkommen vertrauenswürdig, aber schwer
Die von mir vorgeschlagene Option ist sogar etwas optimistisch. Wie wir vertrauten die Umgebung (Browser/Node) ist definitiv für rund 2012-2021, auch ist ein Standard/Famous ein, so erfordern keine besondere Berücksichtigung.
Aber es kann sogar ältere Browser ODER einige unerwartete Probleme geben, und Polyfills können immer noch unterstützen und mehr mögliche Umgebungsprobleme lösen. Für den Fall, dass wir maximale Unterstützung benötigen, die möglich ist, können wir verwenden polyfill libraries
mögen:
https://polyfill.io/
Speziell für replaceAll :
<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>