JavaScript und Webstandards
JavaScript-bezogene Spezifikationen und deren praktischer Einsatz
Nicht schon wieder ein ellenlanger Artikel zur JavaScript-Theorie!
Ich bemühe mich und bitte diese erneute Theorielastigkeit zu entschuldigen, denn der Welt fehlt bisher noch ein Artikel zu der durchaus praxisrelevanten Frage:
Welchen Standards folgt mein JavaScript-Code überhaupt? Wo und wie sind die Techniken, derer ich mich bediene, normativ festgelegt? Wo kann ich sie nachschlagen? An welche Definitionen sollte ich mich halten?
Der Wolkenkratzer ist fertig, doch der Grundstein fehlt noch
Im Forum hatte ich letztens darauf hingewiesen, dass die WHATWG bzw. das W3C das JavaScript-Objekt XMLHttpRequest
standardisieren möchte. XMLHttpRequest ist bekanntlich eine Microsoft-Erfindung, wurde aber von allen großen Browsern übernommen und stellt heuzutage das Rückgrat aller Ajax-Anwendungen dar. Dabei ist mir eine historisch pikantere Entwicklung entgangen:
Das W3C will auch das window
-Objekt standardisieren.
Ja, genau, das oberste JavaScript-Objekt wird standardisiert. Das scheint auf den ersten Blick ein Witz zu sein. window.alert("Ich dachte, das wäre Standard?")
Nunja, jeder JavaScript-fähige Browser versteht es, und, so denkt man, wo kein window
, da auch kein JavaScript. Aber bis heute ist dieser Grundstein bestenfalls ein freiwilliger, nirgendwo festgeschriebener Konsens.
Was ist überhaupt »JavaScript«? – JavaScript und Standardisierung
Wir haben alle eine Vorstellung von JavaScript, aber der Begriff ist tatsächlich äußerst schwammig. Was JavaScript ist und was nicht, kann niemand genau definieren. Mit JavaScript ist meist ein offenes Konglomerat an Techniken gemeint, die eher lose ineinandergreifen. Strenggenommen gibt es kein »JavaScript« als zusammenhängende Technologie und der Vergleich mit HTML und CSS, HTTP, DNS, TCP/IP und anderen Grundlagentechniken ist nicht möglich.
Während bereits seit Jahren von Webstandards geredet wird und es einflussreiche Initiativen gibt, die sich für die Durchsetzung von öffentlichen Standards einsetzen, sind im Bereich JavaScript nur gewisse Teiltechniken durch offene Standards abgedeckt, andere sind proprietäre Eigenerfindungen einzelner Browserhersteller. Diese wurden dann von anderen Browsern übernommen – oder auch nicht. Zudem beruhen die Umsetzungen der Standards teilweise auf einem nicht genau festgelegtem Kitt, der sie in JavaScript nutzbar macht.
Dies mag verwundern, gilt JavaScript doch trotz aller Browserprobleme als eine robuste und zunehmend leistungsfähige Websprache, die mittlerweile immer umfassender und ausgeklügelter eingesetzt wird. Dementsprechend interessant und aufschlussreich ist es, sich die wackligen Füße näher anzusehen, auf denen heutige Scripte aufbauen. Die Lage der Standardardisierung im Bereich JavaScript ist in Kürze:
Die Anfänge: Netscape Core und Client-Side JavaScript
»JavaScript« bezeichnet ursprünglich nur eine Serie von technischen Spezifikationen der längst verblichenen Firma Netscape. Relevant sind bis heute die Client-Side JavaScript 1.3 Reference (1999) sowie die Core JavaScript 1.5 Reference (2000). Alle JavaScript-fähigen Browser, nicht nur die aus dem Hause Netscape, richteten und richten sich nach diesen Spezifikationen.
Was wir unter dem Begriff JavaScript kennen, wurde zum großen Teil durch das »Client-Side« JavaScript erfunden. Mit »Client-Side« ist die Verwendung von JavaScript als Scriptsprache gemeint, die in HTML-Dokumente eingebunden ist, welche ihrerseits in grafischen, fensterbasierten Web-Browsern dargestellt werden. An dieser proprietären Spezifikation aus dem Jahr 1999 hängt bis heute die gesamte JavaScript-Praxis. »Core« JavaScript beinhaltet nur gewisse Sprachgrundlagen, denn Netscape verwendete JavaScript nicht nur auf der Client-, sondern auch auf der Server-Seite. Um Missverständnissen vorzubeugen, werden diese Technologien im Folgenden ausdrücklich Netscape-JavaScript genannt.
Standardisierung der Sprachgrundlagen: ECMAScript
Netscape bemühte sich einst, Core JavaScript zu standardisieren. Heraus kam ECMAScript (ECMA-262), maßgeblich ist heute die dritte Ausgabe (1999). Darin werden alle Grammatik- und Syntaxregeln, die Objektkonzepte und gewisse grundlegende, vordefinierte Objekte bzw. Datentypen festgelegt (sogenannte native objects).
ECMAScript ist ein wirklicher Industriestandard. Trotzdem ist es die schlechteste Web-bezogene technische Spezifikation, die ich kenne. Nahezu niemand kann sie lesen und verstehen, sie ist nicht dafür gemacht, dass ein einfacher JavaScript-Programmierer darin nachschlagen kann. Für Anfänger und Interessierte ist sie gänzlich ungeeignet, denn wesentliche Konzepte werden erst durch erklärende Sekundärliteratur ersichtlich.
Auch wenn viele die Begriffe synonym verwenden: ECMAScript nicht gleich JavaScript und auch nicht der standardisierte Nachfolger von JavaScript. ECMAScript ist eine Meta-Sprache, ein Baukasten für beliebig viele Programmiersprachen. Ähnlich wie XML auf dem Feld der Auszeichnungssprachen lassen sich ECMAScript-Derivate erstellen (implementations). Netscape-JavaScript ist ein solches Derivat, weitere populäre Beispiele sind Macromedia ActionScript (vor Version 2) sowie Microsoft JScript (vor JScript.NET).
ECMAScript ist nicht auf eine sogenannte Host-Umgebung (host environment) beschränkt. Das Szenario World Wide Web + HTML-Dokument + fensterbasierter Browser ist nur ein denkbares. Mit ECMAScript alleine kann man noch nicht viel anfangen, denn ECMAScript definiert keine Host-Objekte, mit denen überhaupt erst Datenzugriff, Ausgaben usw. möglich. Wir treffen in der Praxis also niemals auf reines ECMAScript.
Netscape-JavaScript 1.3 war seinerzeit konform zu ECMAScript Ausgabe 1, Version 1.5 ist eine Angleichung an Ausgabe 3. Netscape Core JavaScript 1.5 ist demnach ECMAScript plus ein paar Netscape-Zugaben und -Eigenheiten. Wichtig ist, dass ECMAScript nur die Grundlagen von Netscape-JavaScript bereitstellt. Der gesamte Client-seitige Teil baut darauf auf, wird aber nicht in ECMAScript definiert.
Relikte von Client-Side JavaScript
Client-Side JavaScript obliegt also die Aufgabe, ein Set an Host-Objekten zu definieren, die der Scriptsprache als HTML-Ergänzung Sinn verleihen. Um uns noch einmal vor Augen zu führen, welche grundlegenden Techniken durch Netscapes Client-Side JavaScript eingeführt wurden, die bis heute breite Verwendung finden:
window
ist das oberste Objekt (das sogenannte globale Objekt im Sinne von ECMAScript) mit diversen Unterobjekten, Eigenschaften und Methoden.- Der Zugriff auf das HTML-Dokument ist über window.document möglich. Jedes Dokument gehört einem Fensterobjekt an.
- Auf HTML-Elemente im Dokument kann man vor allem über document.anchors, document.forms, document.images und document.links zugreifen.
- Frames und Inner Frames bilden eigene »Fenster« und über window.frames ist der Zugriff auf sie möglich.
- window.history und window.location erlauben den Wechsel des gegenwärtig dargestellten Dokuments.
- window.navigator und window.screen geben Auskunft über den Browser und die grafische Oberfläche.
- (document.layers: Das Layer-Konzept war historisch wichtig, spielt heute aber keine Rolle mehr.)
Das aktuelle Maß der Dinge: Das W3C Document Object Model
Das Document Object Model löst Netscapes Client-Side JavaScript größtenteils ab, indem es den Zugriff auf HTML-Dokumente neu regelt und dabei einige Zugriffsarten übernimmt. Gemeint sind vor allem die Spezifikationen DOM Core und DOM HTML. Aber auch DOM Events und DOM Style sind als Nachfolger von Netscapes Client-Side JavaScript zu sehen.
DOM 2 Core und DOM 2 HTML werden, zumindest in ihren wichtigsten Punkten, von den verbreiteten Browsern hinreichend fehlerfrei umgesetzt. Wenn man heute von Webstandards im Hinblick auf JavaScript spricht, so ist meistens der konsequente Einsatz dieser DOM-Techniken gemeint, vor allem in Abgrenzung zu früheren, proprietären DHTML-Praktiken. Was JavaScript heutzutage kann und ist, definiert sich daher größtenteils über das W3C DOM. Der Begriff DOM Scripting als Alternative zu »JavaScript« ist daher nicht weit hergeholt.
Das große Aber folgt auf dem Fuße: Das DOM löst Netscapes Client-Side JavaScript nicht in jeder Hinsicht ab. Das DOM definiert lediglich eine Programmiersprachen-unabhängige Schnittstelle, es wird keine vollständige ECMAScript-Sprache definiert. Zwischen ECMAScript und dem DOM verbleiben Lücken, die durch Bestandteile von Client-Side JavaScript geschlossen werden – allen voran durch das Objekt window
, welches nun standardisiert werden soll.
Standardkonforme Programmierung?
Unter dem Strich haben wir die waschechten Standards ECMAScript und DOM. Können wir uns also darauf verlassen und standardkonforme Scripte schreiben, genauso wie wir validen HTML- und CSS-Code schreiben? Nun, wir können es nicht, solange das Netscape-JavaScript-Erbe noch nicht vollständig durch offene Standards ersetzt wurde und solange die Browser nicht alle relevanten DOM-Standards unterstützen. So wird verständlich, warum das W3C das window
-Objekt standardisieren will.
Auch wenn es den wenigsten bewusst ist, heutige Scripte, die scheinbar konsequent auf der DOM-Schiene fahren, sind ein wilder Mix aus Techniken verschiedener Herkunft und stützen sich an unzähligen Stellen auf veraltete und proprietäre Techniken. Wir betreiben Event-Handling auf dem Niveau von Netscape JavaScript und Microsoft JScript, weil DOM Events nicht hinreichend unterstützt wird. Wir nutzen absichtlich proprietäre Features, weil sie das Web bereichern und die Möglichkeiten vergrößern. Das ist kurios verglichen mit der rigiden Selbstbeschränkung in Sachen HTML und CSS sowie der diesbezüglichen Webstandard-Euphorie.
Sich der eigenen Technikanwendung bewusst werden
Die professionelle Anwendung von JavaScript erfordert, stets im Bilde darüber zu sein, welcher Techniken sich ein Script bedient, welche Spezifikationen diese festlegen und wie es mit der gegenwärtigen und kommenden Browserunterstützung steht. Das Verstehen eines fremden JavaScript-Codes ist meist schwierig, denn es gibt einen Haufen von selbstgewählten Bezeichnern, hinter denen unbekannte Objekte stecken. Nur hin und wieder tauchen bekannte Namen von Objekten, Eigenschaften und Methoden auf. Die wenigsten JavaScript-Programmierer haben all diese Bezeichner im Kopf, deshalb ist das wirkliche Durchschauen eines Scriptes nur nach einiger Einarbeitungszeit möglich.
Es gibt weitere Faktoren, die die Übersichtlichkeit eines Scriptes verschlechtern. Die formale Deklaration von Variablen ist bei JavaScript nicht nötig, Variablen-Deklarationen mit var
sind im ganzen Script verteilt. Zudem ist JavaScript nicht streng typisiert, sodass der Typ einer Variable nicht eindeutig erkennbar ist. Die freie Formatierbarkeit des Quellcodes und oft fehlende Kommentierung tun schließlich ihr übriges.
Beispielanalyse
Anhand eines Scriptbeispiels habe ich versucht, alle Codebestandteile nach den technischen Spezifikationen zu gruppieren, in der die Teiltechniken definiert sind. Es geht dabei nicht um simples Syntax-Highlighting. Es soll illustriert werden, wie sich ein modernes Script verschiedener Standards und Quasi-Standards bedient. Dadurch bekommt man einen guten Überblick über die gegenwärtige JavaScript-Praxis und deren theoretische Grundlagen und kann das eigene Verständnis der Materie vertiefen.
Ich habe mir das Script
Unobtrusive Table Sort Script von Brian McCallister ausgesucht:
JavaScript und Standards an einem Beispielscript
Es sind sicher einige Fehler darin, was den Zweck der Demonstration aber nicht schmälern sollte.
Querverweise
- Einführung in JavaScript und DOM
- JavaScript-Sidebar mit Direktlinks auf die JavaScript-Spezifikationen für alle in SELFHTML beschriebenen JavaScript-Features
- JavaScript-Syntaxverzeichnis
- Linkverzeichnis: JavaScript und DOM
Nachtrag: Die am häufigsten mißverstandene Programmiersprache der Welt
Anschließend an meine Artikelreihe hat Peter Seliger den Artikel JavaScript: The World's Most Misunderstood Programming Language, ein Standardwerk von Douglas Crockford, übersetzt und kommentiert: JavaScript: Die am häufigsten mißverstandene Programmiersprache der Welt. Der Artikel behandelt unter anderem die Standardisierung sowie die Eigenheiten im positiven und negativen Sinne, der Kommentar verweist auf die Weiterentwicklung der Sprache einerseits und der Programmierung andererseits.