Verzeichnisse und ihre Einträge in JavaScript
Bindungen
Auch ein Verzeichnis kann einem Eintragsnamen zugewiesen werden. Dadurch wird der Bezeichner praktisch zu einem neuen Namen für das Verzeichnis. Wir sprechen hier von einer Bindung des Namens an das Verzeichnis.
Beispiel
Wir binden den Bezeichner »a« an das Verzeichnis »this.Math«.
- Auswertung
a = this.Math
Nun kann auch »a« statt »this.Math« verwendet werden.
- Auswertung
this.Math.PI
3.141592653589793
- Auswertung
a.PI
3.141592653589793
Dies kann man beispielsweise zur Abkürzung verwenden, falls der Ausdruck für ein Verzeichnis sehr lang ist.
Bei der Auswertung von »a.PI« wird erkannt, daß der Name »a« an das Verzeichnis »this.Math« gebunden wurde, daher wird dann der Wert des Namens »PI« aus dem Verzeichnis »this.Math« verwendet.
Beispiel
Wir binden den Bezeichner »G« an das Verzeichnis »this«.
- Auswertung
G = this
Nun kann »G« statt »this« verwendet werden.
- Auswertung
G.Math.PI
3.141592653589793
Wir werden später noch Situationen kennenlernen, in denen der Name »this« eine andere Bedeutung hat, als das globale Verzeichnis. Hat man dann aber rechtzeitig vorher schon den Namen »G« an das globale Verzeichnis gebunden, so kann man dann »G« für das globale Verzeichnis verwenden.
Implizite Erzeugung von Einträgen
Oben haben wir folgende wichtige Eigenschaft von JavaScript verwendet.
Durch eine Zuweisung der Form »V.a = …« mit einem schon bestehenden Verzeichnis »V« wird der Eintrag »a« in jenem Verzeichnis automatisch angelegt, wenn er zuvor in dem Verzeichnis noch nicht existierte.
Egal, ob der Eintrag automatisch angelegt wurde oder schon vorher existiert hat, wird sein Wert dann auf den Wert des Ausdrucks auf der rechten Seite des Gleichheitszeichens gesetzt.
Wenn eine JavaScript -Implementation neu gestartet wurde und diese dann den Ausdruck »a = 2« auswertet, geschehen also zwei Dinge:
- Es wird ein neuer Eintrag »a« im Hauptverzeichnis »this« angelegt.
- Der Name »a« jenes Eintrages wird an den Wert »2« vom Typ »number« gebunden.
Dasselbe würde auch passieren, wenn man »this.a = 2;« geschrieben hätte. Falls bei später dann »a = 3« oder »this.a=3« ausgewertet wird, wird dann der schon bestehende Schlüssel »this.a« auf den neuen Wert »3« gesetzt.
Kontexte
Wir können den Wert von »PI« aus »this.Math« nach »this« kopieren und dann »PI« direkt aus dem Hauptverzeichnis verwenden.
- Auswertung
PI = Math.PI
3.141592653589793
- Auswertung
PI
3.141592653589793
»PI« kann dann auch auf die folgenden beiden Weisen ausgewertet werden.
- Auswertung
Math.PI
3.141592653589793
- Auswertung
this.PI
3.141592653589793
Im ersten Fall ist der Kontext (das Ziel, das Zielverzeichnis) der Verwendung dann »Math«, im zweiten Falle »this«.
»global« ⃗
Zur Verdeutlichung, daß mit »this« das „globale“ Hauptverzeichnis gemeint ist, können wir auch einen Eintrag »this.global« anlegen und dann an Stelle von »this« verwenden. Dies kann auch in Situationen hilfreich sein, wenn verdeutlicht werden soll, daß ein Name »n« aus dem globalen Verzeichnis (Hauptverzeichnis) gemeint ist, da dieser da als »global.n« geschrieben werden kann. Außerdem bedeutet »this« an manchen Stellen (wie später behandelt werden wird) nicht mehr das Hauptverzeichnis, während »global« in solchen Fällen seine Bedeutung behält.
- Auswertung
this.global = this
- Auswertung
global.Math.PI
3.141592653589793
Aliaseffekt
Wenn es mehrere Namen für ein Verzeichnis gibt, sind alle gleichwertig und austauschbar.
Dazu legen wir zwei Namen für »this.Math« an.
- Auswertung
a = this.Math
- Auswertung
b = this.Math
Nun legen wir danach einen neuen Eintrag in »this.Math« an:
- Auswertung
this.Math.c = 3
3
Unter Verwendung des Namens »a« erscheint auch sofort der neue Wert, weil »a« den derzeitigen Inhalt von »this.Math« widerspiegelt.
- Auswertung
a.c
3
Man kann auch einen Wert unter Verwendung von »a.c« schreiben und dann diesen Wert unter Verwendung von »b.c« wieder auslesen.
- Auswertung
a.c = 9
9
- Auswertung
b.c
9
Man kann sagen, daß »a« und »b« zwei Aliasse (also alternative Namen) für »this.Math« seien.
Der Begriff „Bindung“ enthält die Möglichkeit, daß mehrere verschiedene Namen an dieselbe Sache gebunden sind.
Die Erzeugung neuer Verzeichnisse
Die Auswertung eines Funktionsausdrucks, wie »()=>0«, ergibt bei jeder Auswertung immer wieder eine neue Funktion, die gleichzeitig auch ein Verzeichnis ist. Daher können wir folgendermaßen ein neues Verzeichnis erzeugen und an einen Namen binden.
- Auswertung
verein = ()=>0
function verein()
Nun können wir Einträge in diesem Verzeichnis anlegen.
- Auswertung
verein.bezeichnung = "Programmierclub"
"Programmierclub"
- Auswertung
verein.bezeichnung
"Programmierclub"
Eine weitere Auswertung des gleichen Funktionsausdrucks ergibt wieder ein neues Verzeichnis ist.
- Auswertung
mitglied = ()=>0
function mitglied()
Nun können wir Einträge in diesem neuen Verzeichnis anlegen.
- Auswertung
mitglied.vorname = "Lotte"
"Lotte"
- Auswertung
mitglied.vorname
"Lotte"
Das zuerst angelegte Verzeichnis »verein« ist unabhängig von dem neuen Verzeichnis »mitglied«.
- Auswertung
verein.vorname
undefined
Wir können allerdings einen anderen Namen an das Verzeichnis »verein« binden, der dann für dasselbe Verzeichnis steht.
- Auswertung
vereinigung = verein
function verein()
- Auswertung
vereinigung.bezeichnung
"Programmierclub"
Die Namen »verein« und »vereinigung« stehen jetzt für das gleiche Verzeichnis, während »mitglied« ein anderes, unabhängiges Verzeichnis ist.
Wir können nun im Verzeichnis »verein« einen Eintrag anlegen, der an das Verzeichnis »mitglied« gebunden ist.
- Auswertung
verein.mitglied = mitglied
function mitglied()
Jetzt haben wir ein Verzeichnismodell (Objektmodell, einen Graphen) gebaut, welches einen Teil der Realität widerspiegelt:
- Auswertung
verein.bezeichnung
"Programmierclub"
- Auswertung
verein.mitglied.vorname
"Lotte"
- Verzeichnismodell
verein (vereinigung)
.--------------------------------. mitglied
| bezeichnung: "Programmierclub" | .--------------------------------.
| mitglied: o----------------------------->| vorname: "Lotte" |
'--------------------------------' '--------------------------------'
Allerdings müssen wir einige, wenige Namen von Einträgen vermeiden, da diese bei Funktionen bereits vordefiniert sind und nicht umdefiniert werden können.
- Auswertung
mitglied.name = "Sommer"
"Sommer"
- Auswertung
mitglied.name
"mitglied"
Ansonsten können wir das Verzeichnismodell jederzeit erweitern.
- Auswertung
mitglied.nachname = "Sommer"
"Sommer"
- Auswertung
mitglied.nachname
"Sommer"
- Auswertung
verein.mitglied.nachname
"Sommer"
- Verzeichnismodell
verein (vereinigung)
.--------------------------------. mitglied
| bezeichnung: "Programmierclub" | .--------------------------------.
| mitglied: o----------------------------->| vorname: "Lotte" |
'--------------------------------' | nachname: "Sommer" |
'--------------------------------'
Übungsfragen
? Auswertungen
Was ist der Wert der mit einem Fragezeichen gekennzeichneten Auswertungen bei der folgenden Folge von Auswertungen?
- Auswertung
a = this
Window → about:blank
- Auswertung
a.b = 2
2
- Auswertung
this.b
- ?
- Auswertung
this.a.b
- ?
- Auswertung
b = this
Window → about:blank
- Auswertung
b.x = 4
4
- Auswertung
a.x
- ?
- Auswertung
a.b.x
- ?
Ergänzungen *
Schlüsselwörter als Bezeichnernamen *
Schlüsselwörter wie »this« dürfen nicht uneingeschränkt als Eintragsnamen verwendet werden.
- Nicht erlaubt
this = 9
Es ist jedoch möglich, in Verzeichnisse auch Einträge einzutragen, deren Name ein Schlüsselwort ist, wenn das Schlüsselwort dabei stets qualifiziert verwendet wird.
- Auswertung
Math.this = 8
8
- Auswertung
Math.this
8
Griechische Buchstaben in Eintragsnamen *
Wir hatten die Syntax von Bezeichnernamen etwas vereinfacht dargestellt. Tatsächlich sind in solchen Namen alle möglichen Arten von Buchstaben zulässig, darunter auch griechische Buchstaben.
Die meisten Programmierer beschränken sich aber auf englische Buchstaben, weil die Übertragung oder Bearbeitung von Quelltext mit anderen Buchstaben manchmal Probleme bereitet.
Beispiel *
Der Programmierer kann eine fehlende mathematische Konstante zum Verzeichnis »this.Math« hinzufügen. Beispielsweise fehlt in »this.Math« die goldene Zahl »φ«. Wir können sie aber leicht nachträglich hinzufügen.
- Auswertung
this.Math.φ = 1.6180339887
1.6180339887
Der folgende Ausdruck zeigt, wie dann der Kehrwert der goldenen Zahl danach ausgedrückt werden kann.
- Auswertung
1/this.Math.φ
0.618033988768953
Der Eintrag »undefined« *
Wenn ein unqualifizierter Name, der nicht definiert wurde, ausgewertet werden soll, dann erhält man eine Fehlermeldung.
- Konsole
etoihqeo
ReferenceError: etoihqeo is not defined
- Konsole
etoihqeo + 1
ReferenceError: etoihqeo is not defined
Es gibt allerdings keine Fehlermeldung, wenn der Name qualifiziert verwendet wird. Dann hat er den Wert »undefined«.
- Auswertung
this.etoihqeo
undefined
- Auswertung
this.etoihqeo + 1
NaN
Ein Vergleich des Wertes eines undefinierten Namens mit »undefined« ergibt »true«.
- Auswertung
this.etoihqeo === undefined
true
Wir können uns auch mit dem Operator »in« vergewissern, daß der Name nicht definiert wurde.
- Auswertung
"etoihqeo" in this
false
Es ist möglich, einem Schlüssel den Wert »undefined« zuzuweisen.
- Auswertung
this.etoihqeo = this.undefined
undefined
Nach dieser Zuweisung existiert der Name in dem angegebenen Verzeichnis, wie mit Hilfe des Operators »in« erkannt werden kann.
- Auswertung
"etoihqeo" in this
true
Ein Vergleich des Wertes eines des Namens mit »undefined« ergibt aber weiterhin »true«.
- Auswertung
this.etoihqeo === undefined
true
Auch die Auswertung des qualifizierten Namens ergibt weiterhin »undefined«, obwohl dieser jetzt definiert wurde.
- Auswertung
this.etoihqeo
undefined
Der unqualifizierte Bezeichner wird nun allerdings als »undefined« ausgewertet, während es eine Fehlermeldung gab, bevor ihm zum ersten Mal ein Wert zugewiesen wurde.
- Auswertung
etoihqeo
undefined
Man sollte einen Eintrag nicht mit dem Wert »undefined« vergleichen, wenn man wissen will, ob diese in einem Verzeichnis existiert, sondern dafür den Operator »in« verwenden, da ein Vergleich mit »undefined« auch den Wert »true« ergeben kann, wenn der Eintrag existiert, aber den Wert »undefined« enthält.
Beispiel *
Als kleinen Zeitvertreib können wir im Verzeichnis »this.this« einen Eintrag »this.this.this« mit dem Wert »this.this« anlegen.
- Auswertung
this.this = this
Damit ist der Wert von »this.this« dem Wert von »this.this.this« gleich, und deswegen ist auch der Wert von »this.this.this« dem Wert von »this.this.this.this« gleich, und so weiter. Wir können danach also beliebige viele »this« hintereinander schreiben, um »this« zu bezeichnen.
- Auswertung
this.this.this.this.this.Math.PI
3.141592653589793