JavaScript: Objekte und Variablen

Objekte, Eigenschaften und Methoden

Ein Objekt ist grob gesagt ein Bündel von Informationen im Speicher. In JavaScript haben wir auf alle zugänglichen Informationen Zugriff als ein Objekt.

Ein Objekt funktioniert als eine Zuordnungsliste, die unter bestimmten Namen weitere Unterobjekte, auch Member genannt, speichert. Diese Unterobjekte teilt man in Eigenschaften und Methoden. Methoden sind ausführbare Funktionen, die dem Objekt zugehören, Eigenschaften sind alle nicht ausführbaren Unterobjekte.

Durch diese Verschachtelung von Objekten entsteht eine beliebig lange Kette von Objekten, die aufeinander verweisen.

Der Browser stellt einem Script eine große Menge von vordefinierten Objekten zur Verfügung. Ein Script nutzt einerseits diese vordefinierten Objekte, indem es Eigenschaften ausliest und Methoden aufruft. Andererseits definiert das Script eigene Objekte. Diese vom JavaScript-Programm selbst eingeführten Objekte werden üblicherweise Variablen genannt.

Konstruktoren, Prototypen und Instanzen

Ein JavaScript-Objekt gehört einem gewissen Typ an. Diese Zugehörigkeit stellt sich in JavaScript so dar, dass ein Objekt von einer Funktion erzeugt wurde. Diese erzeugende Funktion wird Konstruktor genannt. Die meisten Konstruktorfunktionen sind JavaScript-intern und vordefiniert, Sie können allerdings auch selbst definierte Funktionen als Konstruktoren verwenden.

Die Objekte, die ein bestimmter Konstruktor erzeugt hat, werden Instanzen (Exemplare, Abkömmlinge) dieses Konstruktors genannt. Beispielsweise ist ein String-Objekt (eine Zeichenkette) eine Instanz der Konstruktorfunktion String.

Jedes Objekt hat eine Eigenschaft namens constructor, die auf die Konstruktorfunktion verweist, die es hergestellt hat. Beispielsweise liefert "Dies ist ein String".constructor die Konstruktorfunktion String.

Ein Konstruktor ist eine Art Fabrik, die Instanzen nach immer gleichem Muster produziert. Dieses Muster, der Bauplan für die Instanzen ist selbst ein Objekt: Das sogenannte prototypische Objekt, kurz Prototyp. Instanzen sind so gesehen Kopien des Prototypen und werden ihm nachgebildet.

Das prototypische Objekt hängt an der Konstruktorfunktion. Jede Funktion hat eine Eigenschaft namens prototype, die auf das zugehörige prototypische Objekt verweist. String.prototype liefert beispielsweise das Objekt, das den Bauplan für alle String-Instanzen definiert.

Jedes Objekt stammt also von einem Konstruktoren ab, dem ein Prototyp zugeordnet ist. Wenn wir ein Objekt erzeugen, dann wird hinter den Kulissen die entsprechende Konstruktorfunktion aufgerufen. Die Instanz erbt alle Eigenschaften und Methoden des Prototypen, indem sie an das frisch erzeugte, bisher leere Instanz-Objekt kopiert werden. Dieser Vorgang wird prototypische Vererbung genannt.

Prototypen können auch untereinander erben. Auf diese Weise sind die Objekttypen voneinander ableitbar. Ein String-Objekt ist gleichzeitig eine Instanz vom String-Konstruktor wie auch eine Instanz vom Object-Konstruktor.

Das prototypische Objekt ist ein ganz normales JavaScript-Objekt, dem Sie neue Eigenschaften und Methoden hinzufügen können. Auf diese Weise können alle Instanzen, die vom fraglichen Prototypen erben, auf einen Schlag mit neuen Fähigkeiten ausgestattet werden. Diese Methode nennt sich prototypische Erweiterung.

Aus Sicht der JavaScript-Programmierung passieren diese Vorgänge meist unbemerkt. Dass beim Erstellen eines Objektes ein Konstruktor aufgerufen wird und der Prototyp als Vorbild für das Objekt dient, wird nur ersichtlich, wenn wir in diese Vorgänge eingreifen wollen oder eigene Konstruktoren und Prototypen schreiben. Dennoch ist das Wissen um Konstruktoren und Instanzen grundlegend, um den Aufbau der Objektwelt und die Objekttypen in JavaScript zu verstehen.

Klassen – gibt es nicht in JavaScript

Objekttypen und Vererbung werden in vielen anderen Programmiersprachen über Klassen gelöst. JavaScript hingegen kennt keine Klassen, sondern nur die besagten Konstruktorfunktionen und Prototypen. ...

Bezeichner: Objekte ansprechen

Bezeichner (engl. Identifier) sind Namen für Objekte. Um ein vorhandenes Objekt in einem JavaScript anzusprechen oder einen Wert unter einem Namen abzuspeichern, notieren wir dessen Namen.

alert(vorname);

Hier werden gleich zwei Bezeichner notiert: Einmal alert und einmal vorname. alert bezeichnet die vordefinierte globale Funktion, mit der sich Meldungen ausgeben lassen. vorname steht beispielhaft für eine durch das Script selbst erzeugte Variable.

Unterobjekte ansprechen

Um ausgehend von einem Objekt ein Unterobjekt (Member) anzusprechen, notieren wir den einen Objektnamen, dann einen . und danach den Namen des Unterobjekts. Schematisch:

objekt.unterobjekt

Der Punkt (.) ist der sogenannte Property Accessor Operator (engl. Operator zum Zugriff auf Eigenschaften).

Auf diese Weise können wir ganze Ketten an Objektnamen notieren, um das gewünschte Objekt zu fassen zu bekommen:

window.location.href.substring(0, 4)

Hier wird die substring-Methode des durch window.location.href referenzierten String-Objekts angesprochen, um das Protokoll http aus der Adresse (URL) des gegenwärtigen HTML-Dokuments zu extrahieren.

Eine alternative Methode zum Ansprechen von Unterobjekten ist die Klammer-Schreibweise. Dabei wird der Name des Unterobjektes zwischen eckigen Klammern als String notiert:

objekt["unterobjekt"]

Dies hat denselben Effekt wie objekt.unterobjekt. Der Vorteil dieser Schreibweise kommt zum Tragen, wenn der Objektname variabel ist und erst zur Laufzeit des Scriptes feststeht. Zwischen den Klammern lässt sich ein beliebiger Ausdruck notieren, also beispielsweise ein Bezeichner, der auf eine String-Variable verweist:

objekt[stringVariable]

Der JavaScript-Interpreter nimmt den String als Objektnamen und sucht nach einem entsprechenden Unterobjekt.

...

Konventionen für Bezeichner

JavaScript-Bezeichner unterliegen gewissen Regeln, die Sie beim Wählen von Objektnamen beachten müssen:

Ein Bezeichner darf nur aus Buchstaben, arabischen Ziffern (0-9), dem Dollarzeichen ($) sowie dem Unterstrich (_) bestehen. Jedes dieser Zeichen darf an beliebiger Stelle vorkommen, mit Ausnahme der Ziffern, welche nicht an erster Stelle stehen dürfen.

Alle anderen Zeichen (etwa Leer- oder Sonderzeichen) sind in Bezeichnern nicht erlaubt.

Beispiele für erlaubte Bezeichner:

mitarbeiter_name
mitarbeiterName
_mitarbeitername
$mitarbeitername
lohnIn$
mitarbeiter1
twenty4seven

Beispiele für nicht erlaubte Bezeichner:

mitarbeiter name
mitarbeiter-name
mitarbeiter.name
lohnIn€
lohnIn£
2raumwohnung
ein♥FürTiere
arbeiter&angestellte

Buchstaben sind all diejenigen Zeichen, die in der Unicode-Zeichendatenbank als »Letter« gekennzeichnet sind. Das sind eine ganze Menge: Neben dem lateinischen Alphabet gehören Buchstaben mit Diakritika wie ü, ö, ä, ß, é, â, ì, å, õ usw. dazu. Griechische, kyrillische, hebräische, japanische, chinesische Zeichen usw. sind ebenfalls erlaubt.

Allerdings beschränken sich die meisten JavaScript-Programmierer auf lateinische Buchstaben ohne diakritische Zeichen. Der Bezeichner firmengröße ist also möglich, üblicher ist allerdings, firmengroesse zu notieren, um etwa Schwierigkeiten bei der Zeichenkodierung aus dem Weg zu gehen.

Bracket Notation erlaubt beliebigen String

Funktionen und Methoden aufrufen

...

Call-Operator

funktion(parameter)

objekt.methode(parameter)

Das globale Objekt window

Variablen

Gültigkeitsbereich (Scope)

Identifier Resolution

Globale Variablen

Lokale Variablen (Funktionsvariablen)

Objekte erzeugen: Literale und Instantiierung

Objekte können in JavaScript auf zwei Weisen erzeugt werden: Durch einen Literal oder eine ausdrückliche Instantiierung.

Ein Literal (englisch für wörtlich, buchstäblich) ist eine Kurzschreibweise, mit der Sie Werte am schnellsten notieren können. 1.23 ist ein Literal, der ein Objekt vom Typ Number erzeugt. "Hallo Welt!" ist ein String-Literal, true und false sind Boolean-Literale.

Die Langschreibweise erzeugt ausdrücklich eine Instanz eines Kernobjekts, indem es den Konstruktoren aufruft. Wenn wir z.B. ein Objekt vom Typ Array erzeugen wollen, können wir new Array() schreiben.

Nicht alle Objekttypen lassen sich auf beide Weisen erzeugen und das Ergebnis ist auch nicht immer dasselbe (siehe Objekte und primitive Typen). Wenn eine Literalschreibweise für den gewünschten Objekttyp existiert, dann sollten Sie diese nutzen. Für manche Objekttypen existiert keine Literalschreibweise, sodass Sie beispielsweise new Date() notieren müssen.