, (Sonderzeichen)

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Adventskalender 2023 - 16.12. - ,

Das Komma, das unterschätzte Zeichen. Wir benutzen es ganz selbstverständlich beim Schreiben oder beim Aufrufen einer Funktion, um Parameter zu definieren und die Argumente zu übergeben. Wir benutzen es in Array- und Objektliteralen, und fluchen, wenn wir eins vergessen haben und uns JavaScript vor die Füße spuckt.

Wir möchten es gerne benutzen, wenn wir Zahlen präsentieren. Und zwar als Dezimalkomma, nicht als das Tausendertrennzeichen, als dass es uns die englischen Locales unterjubeln wollen. Aber darüber schrieben wir ja gestern schon. Leider fehlt Intl.NumberFormat eine parse()-Methode, mit der man nach deutschen Regeln geschriebene Zahlen automatisch in JavaScript-Werte einlesen könnte, und parseFloat() will unbedingt das englische Locale verwenden. Aber es gibt Tricks, Mike Bostock hatte da eine Idee!

In CSS begegnet uns das Komma in den Selektor-Listen. Diese sind allerdings ziemlich sensibel - wenn man in einer Selektorliste mehrere Selektoren notiert und einer davon kaputt ist, wird die ganze Regel ignoriert. Besser ist die Verwendung von :is(), um eine fehlertolerante Liste zu erstellen. Allerdings - :is() hat seine eigenen Besondernheiten, was die Spezifität angeht.

Ansonsten verwendet CSS das Komma nach Lust und Laune. Manchmal muss man es als Trennzeichen verwenden (zum Beispiel zwischen den Farbstopps in einem Gradienten, machmal wurde es früher als Trennzeichen verwendet (rgb(50, 200, 100)) und heute lässt man es weg - es ist nicht wirklich konsistent.

Die JavaScript-Syntax birgt noch eine Stelle, wo das Komma verwendet wird.

Das vertrackte Komma
console.log(1, 2, 3, 4);      // Ausgabe: 1, 2, 3, 4
console.log((1, 2, 3, 4));    // Ausgabe: 4

In diesen beiden Zeilen hat das Komma eine ganz unterschiedliche Bedeutung. Aber nicht nur das Komma, sondern auch die Klammern!

  • In der ersten Zeile sind die Klammern der Funktionsaufruf-Operator, und darin dient das Komma zur Trennung der Argumente, die an die aufgerufene Funktion übergeben werden.
  • In der zweiten Zeile befindet sich innerhalb des Funktionsaufruf-Operators ein weiteres Klammerpaar, das aber nun die Bedeutung hat, einen Ausdruck zu gruppieren. Denke an console.log(a*(b+2)); - auch hier haben die äußeren Klammern eine andere Bedeutung als die inneren Klammern. Ja, es ist gemein, aber diese Unterscheidung findet sich in sehr vielen Programmiersprachen. Ein Komma, das anderswo als in einer Funktionsaufruf-Klammer verwendet wird, bildet den Aufreihungsoperator. Mit diesem Operator kann man mehrere Ausdrücke hintereinander auswerten lassen, und das Ergebnis ist das, was der letzte Teilausdruck ergibt.

Und weshalb sollte man das tun? JavaScript stammt von C ab, und C gehört zu diesen Sprachen, die den Ehrgeiz besitzen, darin einzeilige Programme beliebiger Komplexität erstellen zu können (der Star dieser Sprachengruppe ist natürlich unangefochten APL...). Wenn man seinen Code unbedingt unlesbar gestalten will, ist es ganz nützlich, mal eben nebenbei noch etwas anderes tun zu können. Eine Funktion aufrufen, eine Variable ändern, was gerade anliegt...

NICHT NACHMACHEN
function berechne(x,y) { return x+y; }
let a = 3, b = 5;
b+=berechne((a+=7,a+2),b-=3);

Welchen Wert haben a und b hiernach? Wenn Du auf 10 und 16 gekommen bist - schade. a==10 ist richtig, der Aufreihungsoperator für das erste Argument erhöht a erstmal um 7, womit es den Wert 10 hat, und übergibt dann a+2, also 12. Für das zweite Argument wird b um 3 vermindert und das Ergebnis übergeben, also 2. Damit liefert berechne den Wert 14. Das sollte auf b==2 aufaddiert werden und 16 ergeben. ABER der += Operator verwendet den Wert von b, den es vor der Auswertung der rechten Seite hatte. Und damit ist b==19.

Natürlich habe ich den gleichen Fehler gemacht. Weshalb die Lektion lautet: Verwende nur pure Ausdrücke für die Ermittlung von Funktionsargumenten (also solche, die keine Nebenwirkungen haben). Andernfalls drohen Bissspuren in der Tischkante!

Es gibt Programme, die JavaScript-Code unleserlich machen und komprimieren. Man nennt sie freundlich "Minifizierer" und aus gutem Grund auch "Uglyfizierer". Diese Programme nutzen den Aufreihungsoperator, um Befehlsfolgen zusammen mit if-Anweisungen in eine Zeile zu packen. Überlasse ihnen den Job, deinen Code unleserlich zu machen. Du selbst solltest – schon damit dein ein Jahr älteres Ich dich nicht hasst – den gegenteiligen Anspruch verfolgen.