it-swarm.dev

Warum ist + so schlecht für die Verkettung?

Alle sagen immer wieder, dass eines der Probleme von JavaScript darin besteht, + [ Beispiel ] für die Verkettung von Zeichenfolgen zu verwenden. Einige sagen, dass das Problem nicht + Verwendet, sondern Typenzwang [siehe die Kommentare aus dem vorherigen Beispiel]. Stark typisierte Sprachen verwenden + jedoch problemlos für Verkettungs- und Zwangstypen. Zum Beispiel in C #:

int number = 1;
MyObject obj = new MyObject();

var result = "Hello" + number + obj;
// is equivalent to
string result = "hello" + number.ToString() + obj.ToString();

Warum ist die Verkettung von Zeichenfolgen in JavaScript ein so großes Problem?

44
configurator

Betrachten Sie diesen JavaScript-Code:

var a = 10;
var b = 20;
console.log('result is ' + a + b);

Dies wird protokolliert

ergebnis ist 1020

Was höchstwahrscheinlich nicht das ist, was beabsichtigt war, und ein schwer zu verfolgender Fehler sein kann.

69
Mchl

Wenn Sie "schlecht" sagen, meinen Sie "falsch" oder "langsam"? Das Argument über die Verwendung mathematischer Operatoren zur Verkettung von Zeichenfolgen ist wohl ein "falsches" Argument, aber es gibt auch ein Argument dafür, dass + viele Zeichenfolgenverkettungen können sehr langsam ausgeführt werden.

Wir reden nicht über "Hello" + number Wenn wir über Leistung sprechen, sprechen wir über den Aufbau einer relativ großen Zeichenfolge durch wiederholtes Anhängen in einer Schleife.

var combined = "";
for (var i = 0; i < 1000000; i++) {
    combined = combined + "hello ";
}

In JavaScript (und C #) sind Zeichenfolgen unveränderlich. Sie können niemals geändert, sondern nur durch andere Zeichenfolgen ersetzt werden. Sie wissen wahrscheinlich, dass combined + "hello " ändert die Variable combined nicht direkt - die Operation erstellt eine neue Zeichenfolge, die das Ergebnis der Verkettung der beiden Zeichenfolgen ist. Sie müssen diese neue Zeichenfolge dann der Variablen combined zuweisen wenn Sie möchten, dass es geändert wird.

Diese Schleife erstellt also eine Million verschiedene Zeichenfolgenobjekte und wirft 999.999 davon weg. Das Erstellen so vieler Zeichenfolgen, deren Größe ständig zunimmt, ist nicht schnell, und jetzt muss der Garbage Collector noch viel arbeiten, um danach aufzuräumen.

C # hat genau das gleiche Problem, das in dieser Umgebung von der Klasse StringBuilder gelöst wird. In JavaScript erzielen Sie eine viel bessere Leistung, indem Sie ein Array aller Zeichenfolgen erstellen, die Sie verketten möchten, und diese am Ende einmal zusammenfügen, anstatt millionenfach in der Schleife:

var parts = [];
for (var i = 0; i < 1000000; i++) {
    parts.Push("hello");
}
var combined = parts.join(" ");
44
Joel Mueller

Es ist nicht schlecht, + sowohl für das Hinzufügen als auch für die Verkettung zu verwenden, solange Sie nur Zahlen hinzufügen und nur Zeichenfolgen verketten können. Javascript konvertiert jedoch bei Bedarf automatisch zwischen Zahlen und Zeichenfolgen, sodass Sie Folgendes haben:

3 * 5 => 15
"3" * "5" => 15
2 + " fish" => "2 fish"
"3" + "5" => "35"  // hmmm...

Vielleicht einfacher: Durch Überladen von "+" bei automatischer Typkonvertierung wird die erwartete Assoziativität des Operators + unterbrochen:

("x" + 1) + 3 != "x" + (1 + 3)
14
kevin cline

Das typische Problem bei der Verkettung von Zeichenfolgen betrifft einige Probleme:

  1. das Symbol + ist überladen
  2. einfache Fehler
  3. programmierer sind faul

# 1

Das erste und wichtigste Problem bei der Verwendung von + Für die Verkettung von Zeichenfolgen nd ist, dass Sie + Für die Verkettung von Zeichenfolgen verwenden und zusätzlich.

wenn Sie die Variablen a und b haben und c = a + b festlegen, besteht eine Mehrdeutigkeit, die von den Typen von a und b abhängt. . Diese Mehrdeutigkeit zwingt Sie dazu, zusätzliche Schritte zu unternehmen, um das Problem zu beheben:

String Concat:

c = '' + a + b;

Zusatz:

c = parseFloat(a) + parseFloat(b);

Dies bringt mich zu meinem zweiten Punkt

# 2

Es ist sehr einfach, versehentlich eine Variable in einen String umzuwandeln, ohne es zu merken. Es ist auch leicht zu vergessen, dass Ihre Eingabe als Zeichenfolge eingeht:

a = Prompt('Pick a number');
b = Prompt('Pick a second number');
alert( a + b );

Erzeugt nicht intuitive Ergebnisse, da Prompt den Zeichenfolgenwert der Eingabe zurückgibt.

#3

Es ist mühsam und nervig, jedes Mal, wenn ich etwas hinzufügen möchte, parseFloat oder Number() eingeben zu müssen. Ich halte mich für klug genug, um mich daran zu erinnern, meine dynamischen Typen nicht durcheinander zu bringen, aber das bedeutet nicht, dass ich meine dynamischen Typen nie durcheinander gebracht habe. Die Wahrheit ist, dass ich zu faul bin, um jedes Mal, wenn ich Addition mache, parseFloat oder Number() abzutippen, weil ich viel Addition mache.

Lösung?

Nicht alle Sprachen verwenden + Für die Verkettung von Zeichenfolgen. PHP verwendet ., Um Zeichenfolgen zu verketten. Dies hilft zu unterscheiden, wann Sie Zahlen hinzufügen möchten und wann Sie Zeichenfolgen verbinden möchten.

Jedes Symbol kann zum Verketten von Zeichenfolgen verwendet werden, die meisten werden jedoch bereits verwendet, und es ist am besten, Doppelarbeit zu vermeiden. Wenn es nach mir ginge, würde ich wahrscheinlich _ Verwenden, um Zeichenfolgen zu verbinden, und das _ In Variablennamen nicht zulassen.

10
zzzzBov