Neuer Artikel: Organisation von JavaScripten
Mathias Schäfer (molily)
- javascript
- selfhtml
0 Siechfred0 Tim0 Rekire0 MaierMan0 Mathias Schäfer (molily)
SELFHTML-Fachartikel stellt Programmiertechniken für moderne, strukturierte JavaScripte vor
JavaScript ist unter neuer Philosophie wieder statthaft geworden, kommt aus der Rolle des missliebigen Kindes heraus und mausert sich zur unverzichtbaren Technik in der Werkzeugkiste der Webentwicklung. Meinem Empfinden nach beschäftigen sich mehr und mehr mit JavaScript. Natürlich kommt dabei auch wenig Erfreuliches heraus, nicht alle JavaScripter sind durch die Schulen der Webstandards und der Barrierefreiheit gegangen.
Doch auch unter dem Vorsatz, dass JavaScript optional unter dem Konzept des progressive enhancement, der fortschreitenden Verbesserung, und mit dem Ziel der Nützlichkeit eingesetzt wird, entstehen Websites, die durch umfangreiche Scripte aufgewertet und interaktiver gestaltet werden.
JavaScript wird zu einer erstzunehmenden Programmiersprache. Dass die neuen Fähigkeiten von JavaScript zunehmend extensiv genutzt werden, erfordert ein Umdenken bei der Scriptentwicklung und beim Scripteinsatz. Während es nichts ausmachte, dass winzige JavaScripte in unstrukturiertem »Spaghetticode« geschrieben waren, bedarf die Programmierung mehrerer, umfangreicher und komplexer Scripte eine durchdachte Planung und Strukturierung.
Ich habe versucht, einen Artikel zur Frage darüber zu schreiben, wie man moderne, ausgelagerte und weiterverwendbare Scripte strukturiert, die den Paradigmen von DOM Scripting und Unobtrusive JavaScript folgen.
Der Artikel ist inbesondere für solche Webautoren interessant, die sich intensiver mit JavaScript auseinandersetzen wollen, größere Projekte mit JavaScript-Verstärkung planen oder einfach fremde Fertigscripte verstehen wollen.
Im angestaubten JavaScript-Kapitel der SELFHTML-Doku sind viele zeitgemäße Programmiertechniken nicht aufgeführt. Und anfängerfreundliche deutschsprachige Quellen, die mit der SELFHTML-Philosophie kompatibel sind, existieren leider nicht. Als Vorgriff auf SELFHTML 9 habe ich daher versucht, in diese ungemein nützlichen, aber leider anspruchsvollen und teilweise trockenen ECMAScript-Grundlagen einzuführen.
Ein solcher theoretischer Schnelldurchlauf ist selbstverständlich problematisch und kann keine umfassende, systematische Einführung ersetzen. Ich hoffe es dennoch, die Gratwanderung zwischen Verständlichkeit und Fachwissen geschafft zu haben, und freue mich über Feedback und Verbesserungsvorschläge: molily@selfhtml.org.
Schöner Artikel, sehr theoretisch und dennoch gut lesbar. Eventuell sollte man noch auf die Möglichkeiten von gettern und settern hinweisen, zumal diese Variante in SELFHTML nicht beschrieben wird. Recht umfassend ist das Ganze auf developer.mozilla.org beschrieben.
Siechfred: Die derzeitige Weiterentwicklung von Javascript hin zu einem JS 2 durch Mozilla und besonders durch die Bemühungen Brendan Eichs sind zwar alle ganz toll – ich mag das von Python geklaute List Comprehension in JS 1.7 – aber sie sind eben erstmal nur bei Mozilla (und anderen eher web-fernen Orten) wirksam und nutzbar. Im Anwendungsgebiet Webseite fehlt es also an Interoperabilität. Und JS 1.5 bis 1.7 und auch das geplante 2.0 sind keine „Standards“, auf deren Fehlen in der Browserunterstützung man empört pochen darf, auch wenn angedacht ist, das langfristig in einer Neuauflage von ECMAScript zu standardisieren.
Und ja, teilweise werden die auch von anderen Browser-Herstellern übernommen, Getter und Setter gibt es auch schon in Nightlies von Safari. Aber im Prinzip sollte man den Innovation erstmal doch etwas Zeit zum Verbreiten geben, ehe man sie empfiehlt. Denn derzeit sind sie erstmal nur ... Experimente. ;)
Vielen dank für den hinweiß mit dem "Organisation von JavaScripten – Programmiertechniken zur Strukturierung von modernen, wiederverwendbaren JavaScripten". Sowas habe ich für mein AJAX-Fotogalerie-Framework gesucht!
Netter Artikel an sich. Allerdings fehlen |prototype|s komplett. Ferner scheint mir dieses Event-Workaround-This-Gemauschel ziemlich "konfus". Richtiger Ansatz mit den closures, aber warum sollte man die Referenz auf |this| in den "global" packen (außer ggf. für Wiederverwendbarkeit)?
|Object| und auch |Function| haben nebenbei noch einiges an "Utilities" zu bieten...
<script type="text/javascript"> function myObj(name) { this.myName = name; } myObj.prototype = { delayAlertSimple: function mO_delayAlertSimple(message, to) { var self = this; setTimeout(function(){alert(self.myName + "\n\n" + message);}, to); }, _doAlert: function mO__doAlert(message) { alert(this.myName + "\n\n" + message); }, delayAlertCall: function mO_delayAlertCall(message, to) { var self = this; setTimeout(function(){self._doAlert(message);}, to); }, _genericDelayedCall: function mO__genericDelayedCall(func, to) { var self = this; var args = []; for (var i = 2; i < arguments.length; ++i) { args.push(arguments[i]); } setTimeout(function(){ func.apply(self, args); }, to); }, delayAlertGeneric: function mO_delayAlertGeneric(message, to) { this._genericDelayedCall(this._doAlert, to, message); } } function myDerived(name, status) { this._name = name; this._status = status; this.myName = this._name + " " + this._status;; } myDerived.prototype = myObj.prototype; var obj = new myObj("hallowelt"); obj.delayAlertSimple("Die Welt sagt hallo!", 1000); obj.delayAlertCall("Und ich grüße zurück!", 2000); obj.delayAlertGeneric("Was eine tolle Welt!", 3000); var obj2 = new myDerived("schöne", "Welt"); obj2.delayAlertSimple("Die Welt sagt hallo!", 4000); </script> <body onload="obj.delayAlertGeneric('loadediload', 10);"> <div id="test" onclick="obj.delayAlertGeneric('Clickediclick', 10);">click()</div> </body>(Unpraktische, aber theoretisch nicht zu verachtende Beispiele)
MaierMan,
Komplizierter und umfangreicher geht immer. Der Artikel hat bewusst keinen Anspruch auf theoretische Vollständigkeit - im Gegenteil, vieles fehlt absichtlich. Ziel war es lediglich, gewisse ausgewählte Strukturen für Einsteiger vorzustellen sowie deren praktische Probleme und Workarounds zu diskutieren. Allgemeines OOP, Vererbung und andere, mächtigere Strukturen waren nicht der Gegenstand des Artikels, der wie gesagt keine systematische Einführung ersetzen soll.
Was ferner dein Beispiel angeht, so sehe ich nicht, was für einen Vorteil es hat, nur öffentliche, nicht-priviligierte Methoden außerhalb des Konstruktors über prototype
zu notieren und dann wiederholt Closures zu erzeugen. Ich habe eigene Objekte vorgestellt, weil ich sie für eine einfache Möglichkeit halte, Scripte zu strukturieren. Man kann die prototype
-Eigenschaft für diesen Zweck nutzen, muss sie als Anfänger aber nicht kennen. Eigene Objekte sind selbstverständlich eine Tür zu weiteren Programmiertechniken, die bei steigender Komplexität nützlich werden. Das geht aber über die Vorstellung einfacher Grundstrukturen hinaus.
Im Übrigen mag dir mein Lösungsvorschlag für Event-Handler konfus erscheinen, aus deinem Beispiel wird mir aber auch keine Alternative ersichtlich. Man kann freilich immer Closures verwenden und das ganze abstrahieren:
var obj = {
handler : function (e, element) {
e = e || window.event;
alert(this + " vs. " + element);
},
addHandler : function (event, element, func) {
var self = this;
element["on" + event] = function (e) {
func.call(element, e, self);
};
},
init : function () {
this.addHandler("load", window, this.handler);
}
};
obj.init();
Das scheint mir jedoch äußerst umständlich, wenn diese Komplexität nicht wirklich erforderlich ist. Frameworks wie Prototype bieten dafür Methoden wie bindAsEventListener
an.
Nachtrag: Ich habe den Artikel jetzt um die Erklärung von bind()
und bindAsEventListener()
ergänzt.
Im Übrigen ist hier nicht der rechte Platz für Detaildiskussionen über Varianten und Alternativen, dazu ist E-Mail-Kommunikation oder unser Forum besser geeignet.