Christian Wansart: Saubere Programmierung mit JavaScript?

Guten Morgen,

zurzeit arbeite ich an einer Software die leider massiv auf JavaScript setzt und habe dort versucht, möglichst sauber zu programmieren. So habe ich eine Klasse „Routing“ die etwa wie folgt aufgebaut ist:

"use strict";

function Routing(map, zoom) {
	this.map = map;
	this.zoom = zoom;

	this.map.centerMap();
}

Routing.prototype.addRoute = function(waypoints) {
	Route.route(waypoints).addTo(map);
}

Und so weiter. Der Quellcode hat natürlich auch über allen Funktionen entsprechende Kommentare, da ich festgestellt habe, dass der Quellcode von JavaScript-Bibliotheken sehr häufig schlecht oder gar nicht kommentiert ist. Dank der Eigenschaften von JavaScript, dass durch den Kontext mal hier und mal da etwas „injiziert“ wird, macht das ganze nicht ganz einfach nachzuvollziehen.

Leider ist nicht mein kompletter Code so aufgebaut, denn mein Code der nach „DOMContentLoaded“ ausgeführt wird, ist eher unübersichtlich, da von einem kleinen Teil immer wieder ein, zwei Zeilen hinzukamen. Ich bin damit etwas unzufrieden und ich denke, ich werde es noch mal überarbeiten müssen.

Die Bibliothek die ich nutze wurde in reinem JavaScript geschrieben und enthält einige Bugs. Aber ich muss auch einige Änderungen vornehmen, damit diese so arbeitet, wie ich mir das vorstelle. Diese nutzen aber nicht den Stil mit prototype sondern mit extend und include was irgendwo im Quellcode definiert wurde, was ich aber nicht vollständig zurückführen konnte. Diesen Methoden wird dann ein Object übergeben, der die Methode in der Form

L.Map = L.extend({
	options: {
		zoomlevel: 7
	},

	initialize: function (id, options) {
		setOptions(options);
		init(id);
	},

	// Weitere Funktionen nach diesem Schema.
});

// Hier fängt es schon an... Was soll sowas?! Also haben wir nun L.map und L.Map, super!
L.map = function (id, options) {
	return new L.Map(id, options);
};

Seit einiger Zeit beschäftige ich mich auch mit JavaScript-Compilern die aus einer vernünftigen Sprache JavaScript erzeugen. Die genutzten Bibliotheken nutzen das leider nicht. Dort kommen grunt, jake also auch „plain old npm“ zum Einsatz. Mein aktueller Favorit unter den Compilern ist TypeScript, da es sehr sauber, und sehr einfach ist und schöne Konzepte anbietet. Das scheint mir auch der Compiler zu sein, der zurzeit am meisten öffentlich sichtbar ist. Was meint ihr? Und was nutzt ihr so?

Ich habe also ein paar mehrere Fragen und würde mich auch über grundsätzliche Einschätzungen freuen.

  1. Wie arbeitet ihr in größeren JavaScript-Projekten um den Quellcode sauber zu halten?
  2. Welchen OOP-Ansatz verwendet ihr, wenn ihr denn einen verwendet?
  3. Wo kommt dieses extend und include her? Kann es sein, dass das von jQuery oder dergleichen kommt? Ich bin mir da ehrlich gesagt nicht sicher.
  4. Bevorzugt ihr JavaScript-Compiler gegenüber reinem JavaScript? Wenn ja, welche gefallen euch und wieso?
  5. Ich glaube ja, dass JS-Compiler das Debuggen erschweren können, weil sie aus class und anderen Konstrukten kryptischen JavaScript-Code erzeugen. Was meint ihr dazu?

Ich bin gespannt und freue mich über jeden Tipp.

Freundliche Grüße
Christian

  1. Tach!

    // Hier fängt es schon an... Was soll sowas?! Also haben wir nun L.map und L.Map, super!

    Nun, das eine ist ein Substantiv, das andere ein Verb. Also Map ist ein Objekt und map tut was konkretes. Dass es sich nur durch Groß/Kleinschreibung unterschiedet ... tja ... bei Hersteller und herstellen sind die Unterschiede beispielsweise auch nicht sehr groß.

    Mein aktueller Favorit unter den Compilern ist TypeScript, da es sehr sauber, und sehr einfach ist und schöne Konzepte anbietet. Das scheint mir auch der Compiler zu sein, der zurzeit am meisten öffentlich sichtbar ist. Was meint ihr? Und was nutzt ihr so?

    Da ich mir andere Konzepte ähnlichen Ziels noch nicht angeschaut habe, kann ich nur antworten: ja.

    1. Wie arbeitet ihr in größeren JavaScript-Projekten um den Quellcode sauber zu halten?

    Ähnlich wie in allen anderen großen Projekten. Übersichtlichkeit erreicht man, indem man die Dinge übersichtlich und nicht kompliziert gestaltet. Das ist eine mit der Projektgröße wachsende Herausforderung. Zm Beispiel keine eierlegenden Wollmilchsäue erstellen sondern separate Tiere. Abhängigkeiten sichtbar gestalten und nciht einfach auf irgendwas zugreifen, was man als außenstehender Verwender nicht sieht.

    1. Welchen OOP-Ansatz verwendet ihr, wenn ihr denn einen verwendet?

    Die Frage verstehe ich grad nicht so recht. Ich nehm Typescript und dann interessiert mich Javascript-Vorgehensweise nicht mehr direkt. Kleinere Projekte in POJS (Plain Old JavaScript) kommen bei mir meist ohne OOP (Prototyp-Verwendung) aus.

    1. Wo kommt dieses extend und include her? Kann es sein, dass das von jQuery oder dergleichen kommt? Ich bin mir da ehrlich gesagt nicht sicher.

    "Go to Definition" in einer IDE, die das kann.

    1. Bevorzugt ihr JavaScript-Compiler gegenüber reinem JavaScript? Wenn ja, welche gefallen euch und wieso?

    Typescript, wenn's mal wieder größer wird.

    1. Ich glaube ja, dass JS-Compiler das Debuggen erschweren können, weil sie aus class und anderen Konstrukten kryptischen JavaScript-Code erzeugen. Was meint ihr dazu?

    Jein. Mit Map-Files zeigen auch die Browser den Typescript-Code an. Klappt dann zwar manchmal mit den Breakpoints nicht. Aber selbst wenn ich im erzeugten JS debuggen muss, bin ich noch nicht wegen Unverständlichkeit dran verzweifelt.

    Zum einen kommt das mit der Zeit, dass man die Äquivalente kennt, zum anderen kann man ja im Playground auf der TS-Webseite und auch beim Vergleich der Dateien im eigenen Projekt die Umsetzung anschauen. Spieltrieb ist dafür eine nicht zu unterschätzende Eigenschaft. Einfach mal schauen, was die da so draus machen aus den verschiedenen Konstrukten. Welche es gibt findet man ja in der Dokumentation.

    dedlfix.

  2. zurzeit arbeite ich an einer Software die leider massiv auf JavaScript setzt

    Willkommen im 21. Jahrhundert :-D

    // Hier fängt es schon an... Was soll sowas?! Also haben wir nun L.map und L.Map, super! L.map = function (id, options) { return new L.Map(id, options); };

    Es wird einen Grund haben, warum das Erzeugen von Instanzen hier noch einmal mit einer Factory-Funktion gekapselt ist. Zum Beispiel könnte hier ein Cache eingesetzt werden, sodass pro ID nur eine Map erzeugt wird.

    1. Wie arbeitet ihr in größeren JavaScript-Projekten um den Quellcode sauber zu halten?

    Verschiedenes ... von der Verwendung von ES6 Modulen, Klassen, funktionaler Programmierung bis hin zu Linting mit Eslint.

    1. Welchen OOP-Ansatz verwendet ihr, wenn ihr denn einen verwendet?

    ECMAScript 6 Klassen. Oder direkt prototypische Vererbung wenn Klassen zuviel sind.

    1. Wo kommt dieses extend und include her? Kann es sein, dass das von jQuery oder dergleichen kommt? Ich bin mir da ehrlich gesagt nicht sicher.

    Das ist wahrscheinlich von einer Bibliothek. Aber nicht von jQuery. Das sieht aus wie die Vererbungstools von Backbone.js oder Ampersand.js.

    1. Bevorzugt ihr JavaScript-Compiler gegenüber reinem JavaScript? Wenn ja, welche gefallen euch und wieso?

    Standardmäßiges ECMAScript 6 mit Babel. Wenn nötig einige Babel-Plugins für zukünftige ECMAScript Features in den höheren Stages.

    1. Ich glaube ja, dass JS-Compiler das Debuggen erschweren können, weil sie aus class und anderen Konstrukten kryptischen JavaScript-Code erzeugen.

    Sie erschweren das Debuggen ein wenig, aber es gibt Source Maps, die einem im Debugger den Originalcode zeigen.

    MfG Kollenda