Warum JavaScript unbrauchbar ist…

Von Googles Idee, eine Alternative zu JavaScript zu etablieren, bin ich bei aller Googleskepsis zu begeistern.

Ich schaue mir schon seit Jahren an, dass Menschen einen Webbrowser für eine Anwendungsplattform halten und immer komplexere Anwendungen damit verwirklichen – natürlich in JavaScript.

Weder ist der Browser eine gute Anwendungsplattform, noch ist JavaScript eine für komplexe Programmierungen geeignete Programmiersprache.

  • Ein Browser ist eine unfassbar aufgeblähte »Runtime« für eine Anwendung. Außerdem hat er (obwohl die im Laufe der Zeit immer unsichtbarer werden, und wird der Browser dadurch auch schwieriger benutzbar) Bedienelemente, die für die eigentliche Funktion des Browsers entworfen wurden, bevor er zur »Runtime« für ein paar Progrämmchen wurde, die es in zehnfach besserer Form (und mit weniger Speicherabdruck und besserer Performance) als Desktop-Anwendungen gibt – diese heiteren Knöpfchen zum Vorblättern, zum Rückblättern und zum Aufruf der eingestellten Startseite zum Beispiel, die in einer derartigen Anwendung sinnlos sind. Über die Sicherheit von Webbrowsern will ich gar nicht reden.
  • JavaScript ist eine unfassbar schlecht entworfene Programmiersprache. Sie enthält syntaktische Schweinereien, die in ihrer Unlogik noch das Chaos der C-Shell überbieten. Es ist leicht, schwer entdeckbare Fehler zu machen; es ist schwierig und aufwändig, auch nur relativ einfache Dinge zu programmieren; es ist ein höllischer Kopfschmerz, wenn in JavaScript eine Programmierung mit ganz normaler, alltäglicher Komplexität erledigt werden muss. Man könnte es jemandem als Strafe auferlegen, der Vater und Mutter erschlagen hat. Wer es nicht glaubt, lade sich eine beliebige JavaScript-Bibliothek für AJAX herunter und analysiere den Code. Auch das könnte man jemandem als Strafe… ach, ich wiederhole mich.

Wer mich kennt, weiß, dass ich JavaScript meide, wann immer es geht. Manchmal geht es allerdings nicht, und dann versuche ich, jede unnötige Komplexität zu vermeiden. Andere sehen das anders und finden es irre cool, wenn in einer im Browser dargestellten HTML-Seite mit mehreren tausend Zeilen Code Dinge realisiert werden, die in einer herkömmlichen Programmiersprache eine Kleinigkeit wären. Wenn derartiger Code allerdings »in Produktion« geht, denn müssen sie darüber nachdenken, wie sich die Funktionalität ohne JavaScript verwirklichen lässt, denn sicherheitsbewusste Anwender (also Leute, die nicht bei Facebook sind und die den Unterschied zwischen den Wörtern »interaktiv« und »interessant« kennen) erlauben aus verdammt guten Gründen nicht jeder dahergelaufenen Website das Ausführen von Code im Browser. Das Ergebnis ist, dass dann noch einmal umfangreiche serverseitige Programmierungen fällig werden, um die Grundfunktionen ein zweites Mal zu implementieren. Die Programmierung ist doppelt, die Tests sind doppelt, die möglichen Fehler sind doppelt… für ein bisschen Effekthascherei. Eine Desktop-Anwendung mit gleichem Funktionsumfang, selbst eine mit aufwändiger GUI unter Zuhilfenahme eines geeigneten Toolkits, ließe sich in einem Bruchteil der Zeit erstellen.

Das syntaktische Chaos von JavaScript erfordert ferner einen Lernaufwand, der über jede andere Programmiersprache hinausgeht. JavaScript ist nicht nur schwer zu schreiben, es ist auch schwer zu lesen. Die folgenden Beispiele für die Unreife und perfide Boshaftigkeit von JavaScript sind bei weitem nicht vollständig, es handelt sich mehr um ein Kuriositätenkabinett, das ich im Laufe meines Daseins gesammelt habe.

Wer nicht programmiert, wird es kaum genießen können. 😉

Der ambige +-Operator und das dynamische Typkonzept

quux = ‘4‘ + 2;

Diese Anweisung weist quux den String "42" zu.

quox = ‘4‘ - 2;

Diese Anweisung weist quox den Integer 2 (Ergebnis der Subtraktion von 2 von der Zahl 4) zu.

Für einen eigenen String-Verkettungsoperator hat es leider beim Entwurf von JavaScript nicht gereicht, und + kann sich sehr eigenartig verhalten. Nicht immer ist klar, dass es sich um einen String handelt, es kann ja eine Variable sein. Die natürlich keinen statischen Typ hat. Die zum Beispiel aus einer XmlHttpRequest-Instanz initialisiert sein kann. Echter Code ist nun einmal viel schwieriger zu verstehen als diese kleinen Beispiele, die einfach nur auf den Punkt kommen wollen. Wer dann mit einem Code konfrontiert ist, der manchmal korrekt läuft und sich manchmal auf völlig unverständliche Weise falsch verhält, hat eine sehr unerfreuliche Sitzung vor sich.

Führende Nullen

Wer verstanden hat, was für Probleme Strings mit numerischen Inhalten machen können, wenn man damit rechnet, ist natürlich dankbar für die parseInt()-Funktion, mit der man bequem Strings in Integers umwandeln kann. Unglücklicherweise können sich dabei auch Fehler einschleichen, die in manchen Situationen sehr schwer zu finden sind:

var quux = parseInt(‘06‘);

Hier wird der Variablen quux der Wert 6 zugewiesen.

var quox = parseInt(‘09‘);

Und hier wird der Variablen quox der Wert 0 (Null) zugewiesen.

Tief durchatmen und dann erst zum Hammer greifen! Eine Ziffernfolge, die mit einer 0 beginnt, wird standardmäßig als Oktalzahl interpretiert. (C-Programmierer haben es schon geahnt.) Und parseInt() bricht mit der Umwandlung bei der ersten nicht legalen Ziffer ab. Aus naheliegenden Fiesheitsgründen natürlich völlig ohne eine Möglichkeit, den Fehler auch irgendwie im Programm zu erkennen, dieses komplizierte Frickelzeug mit Exceptions ist nichts für JavaScript-Programmierer. 9 ist keine gültige Oktalziffer, logischerweise kommt 0 als Ergebnis der Umwandlung heraus. Wer aus irgendeiner Altlast Daten mit führenden Nullen bekommt und damit umgehen muss (oder auch nur mit parseInt() die lästigen Nullen weghaben will), muss also die Basis 10 als zweiten Parameter angeben.

Dass man das leicht vergessen kann… ach, das brauche ich nicht zu sagen.

Die Anweisung return sollte man zurückgeben

function quix()
{
  return 4 + 2;
}

Die Funktion gibt den Wert 6 zurück.

function quax()
{
  return
    4 + 2;
}

Das ist – anders als in jeder anderen Sprache mit C-ähnlicher Syntax – ein syntaktischer Fehler. Oder, in diesem Fall, ein syntaktisch zwar erlaubtes Konstrukt, das sich aber nicht wie erwartet verhält.

Die Designer der Sprache haben sich gesagt, dass return nahezu immer die letzte Anweisung in einer Funktion ist (was nicht stimmen muss). Deshalb wird auf einer Zeile mit return-Anweisung vor dem Zeilenumbruch ein implizites Semikolon eingefügt, das die Anweisung abschließt. Man könnte also, wenn man sich über solche unlogischen Inkosistenzen freut, das Semikolon nach dem abschließenden return in einer Funktion weglassen. Eine return-Anweisung kann also nicht auf der nächsten Zeile fortgesetzt werden. Dies gilt aber nicht, wenn man einen Wert zurückgeben will, der in geschweiften Klammern steht, zum Beispiel ein Objekt mit einer Liste von Eigenschaften. Hierfür muss jedoch die öffnende Klammer auf der gleichen Zeile stehen, in der auch die return-Anweisung steht. Die folgende Konstruktion verhält sich also wie erwartet:

function quox()
{
  return {
    one : 1,
    two : 2,
    three : 3
  };
}

Die folgende Konstruktion gibt hingegen undefined zurück – und dieser Fehler ist für C-Programmierer extrem leicht zu machen:

function quux()
{
  return 
  {
    one : 1,
    two : 2,
    three : 3
  };
}

Die Frage, wer den Sprachdesignern ins Gehirn geschissen hat, kann ich leider auch nicht beantworten. Wahrscheinlich haben sie sich gesagt, dass formatfreie Sprachen so allgegenwärtig sind, dass man Menschen mal mit einer beinahe formatfreien Sprache überraschen muss, die nur bei einem Statement ein bestimmtes Zeilenformat erwartet. Als leicht zu merkende Ausnahme, wenn man es denn weiß. Einfach nur, weil sie ein bisschen närrisch drauf waren. Wer Probleme hat, so etwas nachzuvollziehen, kann sich damit trösten, dass die Programmierer von Webbrowsern ähnliche Probleme hatten. In vielen älteren Browsern hat sich die folgende Konstruktion fehlerhafterweise »wie erwartet« verhalten:

function quatsch()
{
  return /* Kommentarbeginn
    Kommentarende */ 4 + 2;
}

Unvergleichlich dämliche Vergleiche

Keine Lust auf viel Text, einfach nur ein paar Vergleiche mit Ergebnis:

6 == 6;                         /* true, wie erwartet   */
6 == [6];                       /* true, WTF?           */
6 == [[6]];                     /* true, WTHF?          */
‘‘ == ‘0‘;                      /* false, wie erwartet  */
0 == ‘‘;                        /* true, Häh?           */
false == null;                  /* false, wie erwartet  */
false == undefined;             /* false, stimmt schon  */
false == ‘0‘;                   /* true, oh Henker!     */

Dass diese Vergleiche auch »funktionieren«, wenn keine literalen Konstanten, sondern Variablen miteinander verglichen werden, ist klar. Und dass eine dynamische Typisierung die Vorgänge in einem solchen Fall nicht durchschaubarer macht, auch.

Übrigens kommt auch true heraus, wenn man einen String beliebiger Länge, der nur aus Whitespace-Zeichen besteht, mit dem Integer 0 vergleicht. Wer ein bisschen mehr Erfahrung in JavaScript hat, schreibt natürlich drei Gleichheitszeichen, um zu vergleichen – ein gesundes Beispiel kranker Syntax, das inzwischen auf etliche andere Programmiersprachen ausgestrahlt hat.

Habe ich eigentlich erwähnt, dass undefined nur ein Variablenname für eine globale Variable ist, dem man theoretisch auch einen anderen Wert – sagen wir mal true – zuweisen könnte… 😈

Wenn so etwas jemals erforderlich werden sollte oder auch nur in einer bestimmten Situation nützlich erscheint, sollte man sein Projekt neu schreiben. Sofort. Und gar nicht lange darüber nachdenken, wie man die Zuweisung wieder rückgängig macht, wie man also der Variablen undefined sicher wieder den Wert undefined zuweist. Der Rückgabewert einer Funktion ohne Rückgabe – undefined = (function(){}()); müsste eigentlich gehen, aber ich garantiere für nichts. Ich habe es noch nie gebraucht. Ich werde es nie brauchen. Und wenn es doch einmal brauche, muss ich mich sofort umschauen, ob ich vielleicht schon in der Hölle bin. Da kann ich dann vielleicht meine ewige Strafe verkürzen, indem ich mein Leiden verdopple, denn NaN ist ebenfalls eine globale Variable.

(Hoffentlich haben sie wenigstens das bei der ECMAScript-Spezifikation rausgenommen! Und wenn nicht, soll sie der Henker holen!)

Zahlen sind Objekte, wenn der Parser sie als Zahlen erkennt

Zugegeben, das ist eine exotische Angelegenheit, der man normalerweise nicht begegnet. Aber nicht immer ist alles normal, und dann begegnet man dieser Kleinigkeit doch einmal.

quux = "Hallo".toUpper();

Die Variable quux wird erwartungsgemäß auf "HALLO" gesetzt. Dieses toUpper() ist eine Methode für String-Instanzen. Aber…

quox1 = 42.toString();

…ist ein syntaktischer Fehler und weist keineswegs quox1 den String "42" zu. Damit der Parser die Zahl in einer solchen Konstruktion richtig parst, muss sie einen Dezimalpunkt enthalten, also etwa so geschrieben werden (Nullen können wegbleiben):

quox2 = 42..toString();        /* Aua, mein Kopf! */

Wer einen etwas ausführlicheren Stil hat – das soll ja gut für die Lesbarkeit der Quältexte sein – wird das natürlich so schreiben:

quox3 = 42.0.toString();       /* Aua, meine Augen! */

😥

Unerwartet nicht-lokal lokale Variablen

var quux = 42;
function quax()
{
  quux = 23;
  /* Vielleicht ein paar hundert Zeilen Code dazwischen */
  if (irgendeineBedingung)
  {
    /* Eine lokale Variable in diesem Block soll das sein... */
    var quux;
    /* Vielleicht noch ein bisschen Code hierher */
  }
}
quax();

Jeder Programmierer, der eine beliebige andere Programmiersprache (also nicht so etwas wie COBOL) kennt, erwartet, dass nach dem Aufruf der Funktion quax() die globale Variable quux auf 23 gesetzt wurde. Wurde sie aber nicht. In JavaScript haben die lokalen Variablen nämlich nicht wie in anderen Programmiersprachen den Block als Gültigkeitsbereich, sondern die Funktion – und die spätere Definition einer lokalen Variablen quux in einer Funktion verhindert deshalb das vermutlich gewünschte Überschreiben der gleichnamigen globalen Variablen. Einen derartigen Fehler habe ich einmal verdammt lange im Code anderer Leute gesucht, und seitdem ist mein Verhältnis zu JavaScript nachhaltig getrübt.

Dass ein solcher Fehler bevorzugt in etwas längeren Funktionen mit viel Code auftritt, brauche ich wohl nicht zu erwähnen. Man tut gut daran, eine Namenskonvention für globale Variablen einzuhalten… und man hat verloren, wenn man Code »geerbt« hat, in dem das nicht der Fall ist.

this und das

Dieses this kann innerhalb eines Objektes je nach Kontext der Benutzung des Objektes unterschiedliche Werte haben.

<input type="button" value="Aua!" id="auaknopf" />
<script>
var einObjekt = function() {
  this.anzeigeText = "Tut doch nicht weh!";
  this.clickHandler = function() {
    alert(this.anzeigeText);
  }
}();
document.getElementById("auaknopf").onclick = einObjekt.clickHandler;
</script>

Einmal abgesehen von der hirnrissigen Syntax für Objektorientierung in JavaScript sieht das noch durchschaubar genug aus. In richtigen Anwendungen wäre natürlich viel gemeinsame Funktionalität in so einem Objekt für die Event-Behandlung gekapselt und nicht einfach nur eine Instanzvariable und eine Methode.

Unglücklicherweise ist das Verhalten der Methode einObjekt.clickHandler() in diesem Beispiel davon abhängig, wie sie aufgerufen wird. Nach einem Klick auf dem Button »Aua« erscheint eine Messagebox mit dem Text »undefined«, wird die Methode aber direkt aufgerufen, steht »Tut doch nicht weh« drin. Der Wert von this in einem Handler bezieht sich nämlich auf das Element, nicht auf das Objekt – also im Beispiel auf den Button mit der ID »auaknopf«. Dass dieses völlig idiotische kontextabhängige Verhalten es nicht gerade erleichtert, die Komplexität von interaktiv auf Benutzereingaben reagierenden Anwendungen in Objekten zu kapseln, brauche ich wohl nicht weiter zu erwähnen.

Ich habe übrigens schon friedliche Menschen sehr unfriedliche Wörter sagen hören, wenn sie auf dieses Designproblem von JavaScript reingefallen sind.

Wer braucht schon Fehlerbehandlung, negative Nullen sind besser

Die Anweisung…

var quux = 1 / 0;

…setzt quux auf Infinity. Das ist doch viel besser als eine für Programmierer völlig unverständliche Meldung wie… sagen wir mal… Division by zero in file bla.js line 39. Oder vielleicht sogar eine Fehlerbedingung, die sich irgendwie im Programm abfangen lässt. Stattdessen gibt es einfach nur ein Programm, das in manchen Situationen nicht richtig funktioniert und völlig ohne jeden Hinweis versagt. Natürlich ist die 0 in der Regel eine Variable, die auch nicht in jeder Situation 0 ist. Da freut man sich doch über die Sitzungen mit einem Debugger, weil es keine hilfreiche Meldung gibt; da freut man sich über langes schrittweises Durchgehen einer längeren Codepassage, bis man sich endlich die Handfläche ins Gesicht haut. Und danach fragt man sich vielleicht, was man alles Besseres mit dem verdorbenen Tag hätte anfangen können, wenn man eine richtige Programmiersprache für seine Anwendungen verwenden würde.

Aber dafür hat JavaScript wenigstens ein Konzept, das selten ist und das sich direkt an den Erscheinungen der Welt orientiert: Das Konzept der negativen Null, mit der auch gerechnet werden kann. Die Anweisung…

var quox = 1 / -0;

…weist quox nämlich den Wert -Infinity zu. 😎

Ach übrigens, das ist alles sehr dynamisch

So ein Array ist etwas Tolles, denn es ist ein Objekt. Das merkt man nur in der Regel nicht, weil man es in einer zugegebenermaßen guten Syntax wie ein Array benutzt:

var quux = [2, 3, 5, 7, 11];
var product = 1;
for(var quox in quux)
{
  product *= quux[quox];
}

Eine elegante Methode, das Produkt der ersten fünf Primzahlen zu berechnen, nicht? Solchen Code schreibt man ständig, und die Iteration mit einer for()-Schleife ist auch wirklich hübsch. Sie liefert jeden Array-Index in einer Variablen. Das funktioniert auch mit Hashes. Und natürlich auch mit Klasseninstanzen, die übrigens nichts anderes als Hashes sind. Aber das weiß man ja, wenn man in JavaScript programmiert, und das ist alles wahnsinnig elegant. Vor allem wahnsinnig.

Bis die oben genannte for()-Schleife plötzlich nicht mehr funktioniert, während man in einer größeren Anwendung weiterentwickelt.

Man hat doch gar nichts daran geändert, sagt man sich… und sieht doch plötzlich eine Fehlermeldung, die besagt, dass man ein Objekt nicht mit einer Zahl multiplizieren kann. Na, dann greift man halt zu einem guten Debugger (den man zwingend benötigt, wenn man in JavaScript programmiert) und schaut sich mal an, was da abgeht. Und oh Schreck, auf einmal enthält das Array quux nicht nur die ersten fünf Primzahlen, sondern auch ein paar Funktionsobjekte.

Tja, diese praktische Bibliothek, die man da verwendet hat, um sich Arbeit zu sparen, sie hat unter anderem die Schnittstelle der Array-Klasse erweitert. Ist doch toll, dass das genau so einfach wie in Ruby geht. Da muss man nicht das Array beerben, um eine nützliche Methode hinzuzufügen, sondern kann hinterher ganz normal seine Arrays in eckigen Klammern definieren und bei der ganz normalen, hübschen JavaScript-Syntax bleiben. Es ist völlig legales (und ja: sogar elegantes) JavaScript, und ich habe solchen Code schon mehr als einmal gesehen:

Array.doSomething = function() {
  /* Sinnvoller Code hierher */
};

Und dann stellt man fest, dass es auf einmal in jedem Array ein Element mit dem Index "doSomething" gibt, denn es ist ja jedes Array ein Hash. Dieses Element ist die neu definierte Methode. Aus naheliegenden Fiesheitsgründen sind die Standardmethoden wie etwa join() und pop() nicht in dieser Weise implementiert und werden bei einer Iteration niemals sichtbar.

Und dann fängt man an, das alles zu hassen

Genug gesagt

Man sollte JavaScript und die schwachsinnige Idee einer im Webbrowser laufenden Anwendung – meiner bescheidenen Meinung nach – den Chinesen geben, um ihre IT-Technologie auf den Stand des Maoismus zurückzuwerfen. Damit könnte vielleicht der Wirtschaft der westlichen Welt noch für ein Jahrzehnt lang ein gewisser Vorteil gegenüber dem aufstrebenden Staat der kommenden Zeit erhalten werden.

Leider macht das niemand. Obwohl es das Beste wäre.

Leider laufen hier jede Menge Programmierer herum, die ihre beschränkte Lebenszeit damit vergeuden, Anwendungen zu programmieren, die in einem Webbrowser laufen sollen. Sie stören sich nicht daran, dass ihre »Runtime« (also der Webbrowser) widerspenstig, fett und unsicher ist; sie stören sich auch nicht an den kleinen Inkompatibilitäten zwischen den verbreiteten Browsern und binden oft tausende von Zeilen bewährten Codes in einer interpretierten Programmiersprache ein, die zum größten Teil nichts weiter sind als eine Sammlung von Workarounds um diese Inkompatibilitäten. Es ist ihnen gleichgültig, dass so etwas aus Nutzersicht höchstens die drittbeste Lösung ist, denn die Anwender ihres Gehäcksels sind ihnen auch gleichgültig. Es ist ihnen egal, dass die verwendete Programmiersprache unbrauchbar, unlogisch, kaputt, ein Krampf im Arsch ist. Sie sitzen da und freuen sich wie die kleinen Kinder, wenn sie einen einzigen Anwendungsfall in unfassbar komplexem AJAX-Gestrokel realisiert haben, so etwas wie »Der Nutzer trägt ein Wort in ein Eingabefeld ein und drückt Eingabe, und das Wort wird serverseitig in der Datenbank gespeichert und erscheint im Erfolgsfall ohne Neuladen der Seite in einer Wortliste« – etwas, das im Rahmen einer normalen Desktop-Anwendung selbst noch mit einem »zickigen« Toolkit beinahe trivial und ungleich performanter wäre. Es stört sie nicht weiter, dass sie Räder neu erfinden… und dass dabei schlechtere Räder herauskommen. Sie sind fasziniert von der technischen Machbarkeit solchen Unterfangens, aber interessieren sich sonst für gar nichts mehr. Es läuft nicht performant auf Rechnern, die älter als drei Jahre sind? Rechner kosten nichts, das Alte auf die Müllkippe und das Neue kaufen; mögen die giftigen Berge vor den Städten doch zum Himmel wachsen! Es benötigt unfassbar große Mengen Speicher? Es sieht verdächtig nach Effekthascherei aus? Es fügt einfachen Tätigkeiten eine selbst von erfahrenen Programmierern schwer beherrschbare Komplexität hinzu? Alles egal. Es ist möglich, es wird gemacht. Ohne Sinn und Verstand.

Wenn Google es schafft, JavaScript durch eine bessere Sprache abzulösen, wäre das wirklich ein Fortschritt. Denn JavaScript ist unbrauchbar (wenn man damit etwas anderes als einen schnellen, kleinen Hack machen will).

Noch besser wäre es freilich, wenn Google es schaffte, die gegenwärtigen »Web-Programmierer« durch bessere Programmierer abzulösen.

Dieser Beitrag wurde unter Technisches abgelegt und mit , , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

25 Antworten zu Warum JavaScript unbrauchbar ist…

  1. Pingback: Google arbeitet an neuer Webprogrammiersprache | 0x80

  2. Daniel sagt:

    Als Antwort passt ein Ausschnitt aus dem Buch JavaScript: The Good Parts.

    […] Die meisten Leute machen sich in dieser Situation nicht einmal die Mühe, JavaScript zu erlernen, und sind dann überrascht, dass JavaScript deutliche Unterschiede zu den Sprachen aufweist, die sie normalerweise verwenden, und dass diese Unterschiede tatsächlich von Bedeutung sind.

    Das Überraschende an JavaScript ist, dass man Aufgaben erledigen kann, ohne viel über die Sprache oder gar über Programmierung zu wissen. Es handelt sich um eine extrem ausdrucksstarke Sprache. Sie ist aber noch besser, wenn Sie wissen, was Sie tun. Die Programmierung ist ein schwieriges Geschäft und sollte deshalb nie mit Ignoranz erfolgen. […] JavaScript: The Good Parts

    • Franko sagt:

      War wirklich amüsant zu lesen 😀
      Auch wenn ich denke dass die Kritik etwas übertrieben ist. Kritikpunkte wo andere zustimmen kann man eigentlich in jeder Programmiersprache finden. Das kann diverse Gründe haben die auch nicht objektiv rational sein müssen sondern auf die eigene Prägung und Vorlieben zurückgehen.

      So ähnlich wie du es mit JS getan hast kann man eigentlich auch C und C++ in die Tonne klopfen. C und C++ zeichnen sich dadurch aus dass sie viele spezielle Fallstricken bieten und man sehr viele Ausnahmefälle und Details sich merken muss um die zu vermeiden. Ähnlich wie bei einigen Fällen bei JavaScript.

      Trotzdem sind viele von C und C++ nicht weg zu kriegen. Jetzt wo es Rust gibt das viele der Probleme von C++ meidet und dem Programmierer es schwieriger macht unklares Programmverhalten zu erzeugen hat sich daran leider nichts geändert.
      Viele schwören weiterhin auf C++ und verweisen auf die Neuerungen die einige Rust Features abdecken.
      Das man aber immer noch die Altlasten der Sprache mitschleppt, viele C++ Programmierer nur Teilmengen der Sprache beherrschen und C++ Code oft beschissen zu lesen ist stört sie nicht.

      Sie kommen mit Argumenten mit »man kann mit jeder Sprache guten und schlechten Code schreiben« oder »es gibt keine Altlasten in C++ sondern nur sinnvolle Möglichkeiten für jeden unterschiedlichen Anwendungsfall«.

      Der Erfolg des Internets und von Webseiten und Webanwendungen zeigt jedenfalls dass die Schwächen von JS wohl nicht stark genug waren damit die Browserentwickler sich auf eine neue bessere Websprache einigen. Es kommen genug Projekte ans Ziel, somit hat es sich bewährt und ist immer noch gut genug.

      Ich persönlich finde JavaScript gar nicht schlimm sondern die inzwischen total aufgeblähte und riesige Ökosystem einer Webanwendung. Auch die Nutzung von TypeScript als JavaScript Ersatz was ja einem das Leben erleichtern soll ist oft mit komischen und frickeligen Konfigurationen verbunden und funktioniert nicht immer reibungslos mit dem restlichen Ökosystem der Webanwendung. Sehr viel herum konfigurieren, veraltete Konfigurations Tutorials im Internet… mehrere unterschiedliche Konfigurations Dateien für unterschiedliche Module der Entwicklungsumgebung…
      Schrecklich! 😀

      Früher fand ich Textdateien als Konfiguration echt einfach und elegant. Heute ist das aber dermaßen ausgeartet, dass es einfach nur unübersichtlich geworden ist. Auch nett wenn man in der Konfigurationsdatei Angaben hat die inzwischen veraltet und unwirksam sind aber nirgendwo eine Ausgabe darüber erfolgt. Und die oft veralteten Tutorials im Internet sind da auch nicht gerade hilfreich um auf dem aktuellen Stand zu sein. Auch das ist alles kacke und anstrengend. Aber auch damit wird man wohl leben müssen genau wie mit JavaScript 😀

  3. Pingback: Anonymous

  4. Bio sagt:

    Elias, schau mal hier.

    »[…]Zu dem verlinkten Artikel, „[w]arum Javascript unbrauchbar ist“ werde ich gar nicht zu sehr eingehen. Der Autor bringt dynamische und schwache Typsierung durcheinander, versteht scheinbar nicht, dass Funktionen High-Level Objekte sind, und weiß scheinbar nicht, dass 1/0 laut IEE754 wohldefiniert ist. Der einzige Kommentar dort passt ganz gut; man sollte grundsätzlich nichts kritisieren, wovon man keine Ahnung hat, aber das ist heutzutage ja Gang und Gebe.[…]«

  5. Jannik sagt:

    Einige Syntax-Beispiele erscheinen mir durchaus logisch, allerdings nur wenn man Schritt für Schritt denkt und nicht über irgendwelche Optimierungen für Lesbarkeit und Programmierfreundlichkeit nachdenkt 😉
    Trotzdem, dein Artikel hat mich – wie alle anderen – mehrfach zum lachen gebracht, daher +1.

  6. XRay71 sagt:

    Hi,
    ich fand den Artikel eigentlich ganz witzig und gut zu lesen.
    Was ich allerdings bemängeln muss ist die mangelhafte Recherchearbeit. Wenn man sich schon für eine neue Programmiersprache ausspricht, dann sollte man sich auch eingehender damit befasst haben. Hätte der Autor das getan, dann hätte er zum Beispiel festgestellt, dass auch in Google’s Dart 1/0 = Infinity und 1/-0 = -Infinity ist etc.

  7. Manfred sagt:

    Mal unabhängig vom Inhalt: einfach super-lustig geschrieben, Daumen hoch!

  8. Bio sagt:

    Hier mal ein Artikel von einem Flex/AS3 OOP-Entwickler der sich in die neue schöne HTML5/JS Welt begibt.

    Hier ein Ausschnitt – Bitte dort weiter lesen!

    »[…]The problems with JS:

    - Silent errors. They happen. Get ready for them.
    - Hard coupling everywhere. It’s pretty hard to do loosely coupled architectures. It’s quite easy to end up with a web of dependencies between different objects. I‹ve read there are techniques to avoid hard-coupling, but I haven’t had time to dig up more, so this might be my fault.
    - Ugliness. I‹m used to a HUGE-ULTRA-CLEAN separation between classes, libraries, modules, components and applications. In the webdev world, get ready to see PHP spitting HTML that has JS code spitting more HTML… Or function a() that creates another function in object b, that knows about object c and changes how c behaves. Things like that. In many known js libraries.
    - It’s not built for team work. At Webfuel we normally don’t need to talk much with each other about development. Half a dozen guys can be working together for half a year on the same project, committing code every 5 minutes to the same SVN, without breaking the code of others. This was quite easy to achieve much thanks to the structured nature of Actionscript, on top of some very simple practices borrowed from the JAVA world. Enter Javascript and you‹ll see your code breaking the code of someone else. While developing JS in a team, it’s normal that developers need to talk a lot about what each one is doing, warning the other to be careful about X or Y, or asking the other »where did you put the code for…«. Actionscript makes teamwork a joy almost since moment zero – there’s no rocket science for a healthy teamwork environment, especially if you‹re using a micro-framework. In Javascript, the trick is to put people working in very different unrelated parts of the projects and use techniques to encapsulate their code – I have yet to learn them, but I will soon. I‹ve asked some JS developers about this but the ones I know are all lone-wolves so they didn’t understand what I was talking about (apart from the reaction »SVN?? WTF?? Use GIT!«.. hum… that wasn’t my question…)
    - Unpredictable. In AS3, the »this« refers to the instance where the method is defined. In JS, »this« can mean pretty much anything (remember AS2?). This was one of my biggest pain-points at first. Another problem is guessing by looking at the code the properties and functions of an Object. You can‹t. A function in an object can be defined pretty most anywhere. It’s up to you (and your team; and your partners; and your library-providers) to make sure that you keep your house clean with everything organized in the right place.
    - Code practices. These are completely different from everything you know. I taught everyone here at Webfuel to not be afraid of writing many lines of code. I want them to write self-explanatory code, like if they were writing English. Enter Javascript. And cry. By some weird reason, people like to write as much code as possible in a single line, making it not only very hard to read, but also very hard to maintain. I‹ve got used to seeing the $(‹#huge‹).line({of: code, that: function() { looks() }).like(‹a').train(); . And this practice is everywhere, pretty most in all examples, libraries and worse: in books! One of the books I read had one line that took me around 5 minutes to understand! The fun part is that I had the book with me in San Francisco on the Flex Summit and I showed that line of code to several people just to scare the shit out of them. It worked!

    Bottom line: if you‹re an OOP purist, with many years of experience on software engineering on Flex and/or JAVA, you‹re going to be scared. The mindset is different. The problems are different. The solutions are different. Even the slang is different. The good part: no compiling times. Which is actually a very good part…[…]«

  9. Klischeepunk sagt:

    Deine Kritik ist allen ernstes: Wenn du schlecht programmierst, ist das Ergebnis auch scheiße? Wow…

  10. UH sagt:

    Wieso sollte 6 nicht das gleiche sein wie [6]?
    Man kann in fast jeder Sprache belibig viele Klammern um Werte setzen.
    string s = (»bla«))))));
    Ist in C# oder Java zb 100% valide, aber eben genau so Unsinnig wie dieser Kritikpunkt an Javascript.
    Ganz nebenbei gesagt kann man in der Mathematik auch soviele Klammern setzen wie man will. 4+2 ergibt 6, genau so wie (4+(2)) ebenfalls 6 ergibt.
    ‘‘ == ‘0‘ und false == ‘0‘ ist auch soetwas, das einem C Programmierer bekannt vorkommen würde und vollkommen logisch ist.

    Solche Gebilde

    function quax()
    {
    return
    4 + 2;
    }

    sind vom Codingstyl her ebenfalls absoluter Müll.
    Auch das ist kein Kritikpunkt an Javascript, im Gegenteil: Es zwingt den Entwickler dazu, sauber zu programmieren.
    Längere return-Statements gehören in Zwischenvariablen ausgelagert, und wer das Ergebnis von 4+2 zurückgeben will und nicht gerade auf den Kopf gefallen ist wird das auch in einer Zeile tun.

    Dasselbe bei dieser netten Funktion hier:

    function quux()
    {
    return
    {
    one : 1,
    two : 2,
    three : 3
    };
    }

    Irgendein Idiot hat sich (ganz offensichtlich unter sehr starkem Drogeneinfluss) mal in den Kopf gesetzt, für jede aufgehende geschweifte Klammer eine neue Zeile zu verschwenden.

    Anstatt sich über Leute aufzuregen, die hier 2 Zeilen (in größeren Projekten auch mal locker hunderte bis tausende) Platz komplett willkürlich verschwenden, regt man sich natürlich lieber darüber auf, wieso dieses häufchen Elend nicht funktioniert – sehr Intelligent, wirklich!

    Den ganzen Rest entsprechend richtig zu stellen erspare ich mir jetzt mal, hier ist es ähnlich wie in den anderen von mir angesprochenen Beispielen.

    Das einzige was ich hier nachvollziehen kann ist der Sicherheitsaspekt. Flash und Java (Applets) haben zwar viel mehr und vorallem viel gefährlichere Sicherheitslücken (Ich sag nur Java Drive-By), aber hey: Wen interessiert das schon?
    Javascript zu kritisieren macht doch viel mehr Spaß! Erst Recht wenn man dort kritisiert wo es eigentlich gar nichts zu kritisieren gibt.

    Auf jeden Fall amüsant zu lesen, wie jemand mit offenbar 0 Kompetenz versucht Javascript schlecht zu reden 🙂

    • Wieso sollte 6 nicht das gleiche sein wie [6]?
      Man kann in fast jeder Sprache belibig viele Klammern um Werte setzen.

      Der Unterschied zwischen runden Klammern, mit denen man analog zur Schreibweise in der Mathematik eine bestimmte Reihenfolge der Auswertung eines Ausdrucks festlegt (entweder, weil die Standard-Rangfolge davon abweicht, oder aber, weil die Standard-Rangfolge so unintuitiv ist, dass man die Klammern wegen der Deutlichkeit setzt) und eckigen Klammern, mit denen man ein Array definiert, ist aber schon klar? 😉

      Über Stil kann man ansonsten lange streiten, das ist so ein »religiöses« Thema. Wer will, dass die Sprache einen bestimmten Stil des Programmierers erzwingt, ist mit Python jedenfalls besser bedient. (Und ja, ich mag Python, genau wegen dieser Entscheidung. Und ja, ich könnte auch ein paar Worte über miese Ideen im Entwurf der Sprache Python schreiben.) JavaScript verhält sich fast immer wie eine formatfreie Sprache, die keinen Stil erzwingt – mit Ausnahme einer einzigen Anweisung, nämlich return.

      Unter Drogeneinfluss kann ich übrigens nicht proggen. Jedenfalls nicht so, dass das Ergebnis überzeugt. 😉

  11. Java/JAs3Developer sagt:

    Sehr gut erkannt und endlich wird das thematisiert, dass JS eine miese Sprache ist! Ich habe Angewandte Informatik Studiert und kann nach mehreren Jahren Berufserfahrung die Kritik einfach nur bestätigen! Dass wir 2012 JS haben ist ein Armutszeugnis für die gesamte Informatik… Script kiddies haben jetzt keine Ahnung was ich sagen möchte, oder? Wow was man mit einer Zeile JS Code proggen kann, wofür man in JAVA 10 Zeilen braucht – WOOW… jaja.. das ist die Denkweise der Befürworter… ich sag nur »Wenn man keine Ahnung hat, einfach mal die Fresse halten!«

    • Ich schätze übrigens Sprachen, in denen man eine sehr mächtige Zeile formulieren kann. Ohne Perl wäre ich schon manches Mal aufgeschmissen gewesen. Aber es gibt eben Dinge, die man besser nicht in Perl machen sollte. Die Komplexität eines Projektes wächst ja so lange exponentiell, wie alle Beteiligten die Übersicht behalten, und danach geht es im Kriechgang weiter – und diese zweite Phase kann in Perl sehr schnell erreicht werden. (Genau so, wie es Dinge gibt, für die Java etwas… ähm… oversized ist.)

      Die Wahl des zur Aufgabe passenden Werkzeugs (und mehr ist eine Programmiersprache nicht) ist Bestandteil der Kunst.

  12. entwender sagt:

    Als Erstes: Sehr geil geschrieben. Polemisch, aber geil!
    Dass man sich mit solchen Aussagen sofort Feinde schafft, ist klar. Trotzdem hast du in den meisten Punkten recht. An die JS-Fans:

    Der Autor sagt doch hauptsächlich aus, dass in größeren Anwendungen JavaScript oft die falsche Wahl ist. Und das ist definitiv wahr. Je komplexer die Software, desto unbrauchbarer wird JavaScript (und auch sonstige dynamisch typisierten Sprachen, JS ist dazu auch noch schwach typisiert). Wer mit Software zu tun hat, der weiß, dass Laufzeitfehler tödlich sind. Bei statisch typisierten Sprachen können viele Fehler durch den Compiler frühzeitig entdeckt werden. Von Exceptions fang ich gar nicht erst an. Das Dümmste, was man hierauf sagen kann, ist, dass man dann halt aufpassen muss, dass man »gut« programmiert (siehe Kommentare oben, zB Klischeepunk). Sobald man an einem komplexeren System programmiert, viell. sogar mit mehreren Leuten (soll vorkommen), werden Fehler passieren, weil der durchschnittliche Entwickler Fehler macht. Dann macht es schon einen Unterschied, ob diese zur Compile-Zeit oder zur Laufzeit entdeckt werden. Wenn aber ein jemand, nennen wir ihn Klischeepunk, eine Website für Mutti programmiert (Inhalt: Klischees über Punks), dann machen Laufzeitfehler halt nichts aus, weil die Seite keine Sau interessiert. Außer Mutti.
    Ach ja, wo ich schon persönlich werde: UH, du sparst also Zeilen, indem du Klammern keine eigene Zeile gönnst? Ich verwende Entwicklungsumgebungen, die haben ganz viele Zeilen. Such mal in diesem Internet.
    JS erlaubt soviel Scheiße, aber ausgerechnet beim Return-Statement zwingt es den Programmierer, sauber zu programmieren?

    Btw: Nur weil 1/0 tatsächlich von irgendwem als Infinity definiert wurde, ist es nicht weniger schwachsinnig. Mathe: 6, setzen. Nur Chuck Norris kann durch Null teilen.

    • Klischeepunk sagt:

      Ich weiss, ich weiss, ist schon ne Weile her, anyways. Da ich nur für Mutti schreibe kein Ding.

      Nun gibt es auch in der Programmierung regeln die man zu befolgen hat. Basta. Das man die nicht immer einhält ist klar, und das Fehler auftauchen auch. Es ist aber nicht Schwäche einer Sprache wenn man sich nicht an die Regeln dieser hält und der Interpreter dich vernünftigerweise Missversteht. Dem ist nämlich egal was du wolltest.

      Es ist so ne kleine Kunst für sich, sich zu verbessern. Das wird durch viele Projekte angestrebt um genau den Tretminen die einem Sprachen in den Weg legen auszuräumen.

      Daher geh ich nun weiter für Mutti Coden und du codest mit deinem 2 Millionen Mann Team an einer Methode und wunderst dich, wieso es Monate dauert Hello World zu erhalten.

      Ich teile Kritik an JS – aber nicht diese.

  13. HuiBui sagt:

    Ja, völlich richtige Einstellung des Autors! Wir schaffen das ganze Internet in der jetzigen Form ab und machen nur ftp Server auf, dann kann sich jeder, der eine Seite angucken möchte, eine Desktopanwendung runterladen.

    • Da hat jemand vermutlich nicht mitbekommen, dass ich auch einen Gopher-Server betreibe – denn unter Bezugnahme darauf hätte man die Polemik noch ein bisschen absurder und lächerlicher machen können… 😉

  14. BlackCat sagt:

    Also an sich ganz gut geschrieben muss ich ja zugeben, aber viele der Beispiele sind nicht optimal gewählt.

    Ich mein was ist daran nicht zu verstehen?

    return
    4+2;

    ist undefined. Na klar muss auch so sein. In einer Sprache in dessen Definition ein return + Nichts undefined zurückgibt muss die obere Zeile bei nicht erzwungenen Statement Ende dies zurückgeben. Wenn man entgegen der Sprachdefinition programmiert kann man dass doch nicht der Sprache anrechnen.

    Natürlich ist JS keine Sprache ( Hey was ist jetzt in dem Kontext eigentlich perfekt ) aber man sollte schon passende Beispiele für das Bashing heraussuchen. Das gleiche mit ParseInt.. die Kritik mag berechtigt sein ( auch wenn ein Blick in die Spezifikation, was ein guter Programmierer getan hätte, Aufschluss über jenes Verhalten gegeben hätte. Aber verstehen kann ich es trotzdem, ist aber eine Kritik die an die API geht und nicht an die Sprachdefinition. Das sind unterschiedliche Sachen.

    Anderes kann ich nachvollziehen. Ich hätte auch gerne das == als Identitäts-Vergleich gehabt und nicht ===, aber wenn man das weiss ( was man tun sollte wenn man mit JS programmiert ) ist das kein Problem.

    Div / Zero
    Ist ganz Trickreich oder ? Mathematisch kann man darüber streiten ob X/0 undefiniert ist oder bei Grenzwertbetrachtung eher Unendlich ist.

  15. Pingback: Nachtwächter-Blah » Was proggen wir denn jetzt mal in JavaScript? Is…

  16. Sehr gut!

    Deine zynische Art gefällt mir und trotzdem kommen wir fast gar nicht mehr drum rum es zu benutzen XD…

    Ich als ehemaliger Actionscript3-Coder, der noch aus der Zeit stammt, wo nur Flash im Browser enabled war, weil Javascript ja bekanntermaßen Teufelszeug war findet es am schlimmsten, dass man Funktionen in Funktionen schachteln darf :‹(

  17. Pingback: Die wenigsten gemochten Programmiersprachen - Delphi-PRAXiS

  18. Adrian sagt:

    Ja, Javascript ist nicht gerade eine schöne und verständliche Sprache.

    Und schon schreiben wir das Jahr 2019, im Web ist eine kleine Ewigkeit vergangen. Mittlerweile schreibt man TypeScript oder springt wissend über die kleinen Fallstricke.

    Das böse Stöckchen, über das mit Javascript zu springen ist, nennt sich für mich immer noch Callback.

  19. Slava sagt:

    Ich kann nur zustimmen, dass JavaScript eine Straffe ist.
    Schon aus dem Grund, dass sie nicht Geschaft haben THIS so implementieren, dass es für jeden anderen Programmierer verständlich ist, gehört diese Sprache in die Tonne oder in die Hand von Jemandem, dem alle Fortschritte von OOP fremd sind.
    Ich programmiere seit mehr als 20 Jahren und jetzt sitze ich bei einer Javascript-Aufgabe mit Vue-Bibliothek und fühle mich wie ein Berufsanfänger, den man die Kollegen veräppeln versuchen!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert