JavaScript und Webstandards

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:

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

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.

6 Kommentare » Schreibe einen Kommentar

  1. Danke für die Info. Leider hält das jeder anders, so dass man nie weiß, woran man ist. Es sei denn, man fragt nach :)

  2. Usul,

    Wenn wir nicht ausdrücklich notieren, was geändert oder überarbeitet wurde, dann wurden nur kleine Fehler wie z.B. Rechtschreibfehler oder Satzbaufehler geändert. In diesem Fall war ein Satz grammatikalisch fehlerhaft. Inhaltlich habe ich nichts nachgetragen.

  3. Laut meinem Newsreader hat sich dieser Artikel am 30.04.2006 geändert und wurde mir daher neu vorgelegt. Frage: Spinnt mein Newsreader, oder was hat sich geändert? Falls sich was geändert hat, wäre es vielleicht nicht verkehrt, dies unter dem Artikel zu erwähnen, manchmal ändert sich nur ein URL, manchmal kommt ein Update-Absatz dazu, manchmal nur ein Update irgendwo im Artikel selber. Falls mein Newsreader nicht spinnt, wäre etwas mehr Transparenz angebracht.

    Vielleicht bin ich auch nur blind und hab den Hinweis auf die Änderung übersehen :)

  4. Mollily, genau die langen theoretischen Artikel machen den Reiz des SELFHTML Weblogs aus. Was noch ein bischen fehlt ist ein anderer Theoretiker, der die andere Seite des Web beleuchtet, die des Inhalts in form von (X)HTML (2, 5), XML, X-Forms, X-Frames und was es da noch alles interessantest gibt. Ich denke da vor allem an dich Tim, du hattes am anfang ja schon vor über einige Sachen hier zu bloggen, hast du keine Zeit oder keine Lust gefunden?

  5. Ich bezweifle auch nicht, dass die sogenannten Collections images, applets, links, forms und anchors in DOM HTML standardisiert sind. Ich schreibe ja auch: »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.« Damit sind die Collections gemeint.

    Ich habe die Collections genannt, um frühere Dokument-Zugriffsmethoden zu illustrieren, eben DOM Level 0. In der Liste sind es (abgesehen von gewissen document–Eigenschaften und –Methoden) übrigens die einzigen Features, die durch das DOM standardisiert wurden.

  6. Ähm .. document.images und document.konsorten sind standardisiert, nämlich in DOM 2 HTML und Vorläufer. Allerdings stimmt es, dass es Relikte aus Zeiten der Vorstandardisierung sind, in den DOM-Spezifikation als DOM 0 bekannt:

    DOM Level 0
    The term „DOM Level 0″ refers to a mix (not formally specified) of HTML document functionalities offered by Netscape Navigator version 3.0 and Microsoft Internet Explorer version 3.0. In some cases, attributes or methods have been included for reasons of backward compatibility with „DOM Level 0″.

    (Wie kommt das eigentlich, dass Du mir das Thema wegschnappst, über das ich schreiben wollte, ey? ;)