String.concat funktioniert im Firefox 68 nicht mehr
Felix Riesterer
- javascript
- zur info
Liebe Mitlesende,
hatte ein Uralt-Script von mir heute in den Händen, welches Strings nicht "addiert", sondern tatsächlich String.concat(a, b, c)
stattdessen verwendet. Das gibt es in FF68 nicht mehr. Wenn man das unbedingt wollte, müsste man jetzt String.prototype.concat(a, b, c)
verwenden - also lieber doch "addieren".
Liebe Grüße
Felix Riesterer
Hallo Felix,
hatte ein Uralt-Script von mir heute in den Händen, welches Strings nicht "addiert", sondern tatsächlich
String.concat(a, b, c)
stattdessen verwendet. Das gibt es in FF68 nicht mehr. Wenn man das unbedingt wollte, müsste man jetztString.prototype.concat(a, b, c)
verwenden - also lieber doch "addieren".
String.prototype.concat
solltest du nicht so wie oben beschrieben verwenden, sondern so, wie es gedacht ist:
const a = 'Hallo';
console.log(a.concat(' Felix', ', wie geht es dir?'))
LG,
CK
Lieber Christian,
sondern so, wie es gedacht ist:
const a = 'Hallo'; console.log(a.concat(' Felix', ', wie geht es dir?'))
aha, "wie es gedacht ist"? Nun, warum nannten sie die Methode dann nicht append
oder extend
? Das Verb concatenate bedeutet "verketten". Damit wäre auch meine ursprüngliche Verwendung "gedacht".
Man kann nur dazu raten, dass man Stringverkettungen in JS besser mit den +
-Operator anstatt dieser Methode vornimmt.
Liebe Grüße
Felix Riesterer
Hallo Felix,
sondern so, wie es gedacht ist:
const a = 'Hallo'; console.log(a.concat(' Felix', ', wie geht es dir?'))
aha, "wie es gedacht ist"?
Alle Methoden in String.prototype
sind dafür gedacht, direkt auf einem String-Objekt angewendet zu werden.
Nun, warum nannten sie die Methode dann nicht
append
oderextend
?
Extend ist ein Schlüsselwort, das wäre eine schlechte Wahl. Ansonsten: das frag am besten das standards comitee. 😉
Das Verb concatenate bedeutet "verketten". Damit wäre auch meine ursprüngliche Verwendung "gedacht".
Als Methode im String
-Objekt ja, als Methode in String.prototype
nein.
LG,
CK
Hallo Christian,
Alle Methoden in
String.prototype
sind dafür gedacht, direkt auf einem String-Objekt angewendet zu werden.
leider nicht alle. Replace wirkt nur auf den Rückgabewert.
Gruß
Jürgen
Hallo JürgenB,
Alle Methoden in
String.prototype
sind dafür gedacht, direkt auf einem String-Objekt angewendet zu werden.leider nicht alle. Replace wirkt nur auf den Rückgabewert.
Bitte?
"abc".replace(/a/, 'b');
LG,
CK
Hallo Christian,
Hallo JürgenB,
Alle Methoden in
String.prototype
sind dafür gedacht, direkt auf einem String-Objekt angewendet zu werden.leider nicht alle. Replace wirkt nur auf den Rückgabewert.
Bitte?
"abc".replace(/a/, 'b');
wenn du das in der Console eintippst, wird dir der Rückgabewert angezeigt.
Versuch mal
text = "abc"; // -> "abc"
text.replace("a","b"); // -> "bbc"
text // -> "abc"
Getestet im FF 68.
Gruß
Jürgen
Hallo JürgenB,
wenn du das in der Console eintippst, wird dir der Rückgabewert angezeigt.
Versuch mal
text = "abc"; // -> "abc" text.replace("a","b"); // -> "bbc" text // -> "abc"
Ich glaube, du hast mich missverstanden. Ich sagte, die String.prototype
-Methoden sind dazu gedacht auf String-Objekte angewandt zu werden, also 'abc'.replace('a', 'b')
statt String.replace('abc', 'a', 'b')
– ich sagte nicht, dass String.prototype
-Methoden destruktiv sind.
String-Objekte in JS sind immutable, keine der String.prototype
-Methoden ist destruktiv, sie geben alle einen neuen String zurück.
LG,
CK
Hallo Christian,
Ich glaube, du hast mich missverstanden. …
so isses.
String-Objekte in JS sind immutable, keine der
String.prototype
-Methoden ist destruktiv, sie geben alle einen neuen String zurück.
leider. Ich habe daher heute morgen im Bus ein replace gebastelt, das direkt im String durchgeführt wird. Da bei mir die Anzahl der Ersetzungen proportional zur Stringlänge ist, musste ich einen String mit 150*n Bytes n-mal umkopieren, also Ordnung n². Jetzt habe ich Ordnung n.
Gruß
Jürgen
Hallo Felix,
extend oder append vs concat
Nein, die Namen sind schlecht. a.extend("b") oder a.append(y) suggeriert, dass a modifziert wird. Methoden dieses Namens und mit dieser Semantik gibt es an etlichen Stellen (DOM, jQuery). Strings sind in JS aber unveränderlich (immutable).
Man kann nur dazu raten, dass man Stringverkettungen in JS besser mit den +-Operator anstatt dieser Methode vornimmt.
Als universeller Rat ist das nicht zu empfehlen, beides hat seinen Sinn. Und die concat-Methode auf dem Prototypen ist im ECMA Standard und dürfte daher zukunftssicher sein.
Ein binärer Operator verknüpft zwei Objekte und liefert ein neues. Wenn ich eine Folge von Verkettungen habe: "Hallo " + name + ", du bist " + alter + " Jahre alt", werden auf diese Weise 3 Zwischenobjekte erzeugt, d.h. auf dem Heap übereinander gestapelt und wieder verworfen. Nur das letzte bleibt übrig und darunter ein Loch, das der Garbage Collector flicken muss.
Die concat-Methode kann die Längen aller Segmente vorab bestimmen, einen neuen Stringbuffer der benötigten Länge allocieren und die Segmentinhalte dort zusammenfügen. Das ist schneller und belastet den Heap weniger.
Ob es performanter ist, für mein Beispiel oben einen Template String zu verwenden, müsste man messen. Ist aber Mikrooptimierung und im Normalfall wurscht.
Ob die JS Engines der heutigen Browser im Stande sind, eine Folge von + Operationen auf Strings beim JIT Compile zu erkennen und in ein concat umzuwandeln, müsste man ebenfalls eruieren. Diese Optimierung gibt's beispielsweise in C#.
Rolf
Hallo Rolf,
Ob die JS Engines der heutigen Browser im Stande sind, eine Folge von + Operationen auf Strings beim JIT Compile zu erkennen und in ein concat umzuwandeln, müsste man ebenfalls eruieren. Diese Optimierung gibt's beispielsweise in C#.
Hättest du diesen Teilsatz nicht angefügt, hätte ich dir heftigst widersprechen müssen 😉 denn Benchmarks zeigen, dass +
und +=
schneller sind als concat
– und auch als [].join()
, und das in allen JS-Engines bis runter auf IE. Da ist eine Menge Optimierungsaufwand betrieben worden.
LG,
CK
@@Rolf B
Ein binärer Operator verknüpft zwei Objekte und liefert ein neues. Wenn ich eine Folge von Verkettungen habe: "Hallo " + name + ", du bist " + alter + " Jahre alt", werden auf diese Weise 3 Zwischenobjekte erzeugt, d.h. auf dem Heap übereinander gestapelt und wieder verworfen. Nur das letzte bleibt übrig und darunter ein Loch, das der Garbage Collector flicken muss.
`Hallo ${name}, du bist ${alter} Jahre alt`
dürfte diesbezüglich besser sein, oder?
Außerdem ist es besser lesbar, IMHO.
(Wenn’s auch in Uralt-Browsern laufen soll, muss man das freilich durch einen Transpiler laufen lassen.)
LLAP 🖖
Hallo Felix,
ja. Die waren eine Erweiterung des Fuchses (bzw. des Spinnenaffen), die es nicht nach ECMA geschafft hat.
Sie wurden im FF53 missbilligt, aber die Füchse haben es im FF68 nicht für nötig befunden, den Übergang von deprecated zu removed aufzuschreiben. Man findet es indirekt hier, und hier.
Niemand hindert Dich, einen retro-Polyfill zu bauen, falls das für deine Zwecke einfacher ist 😉
Rolf