JavaScript object basics

In diesem Artikel betrachten wir die fundamentale JavaScript Objekt Syntax und betrachten erneut einige JavaScript-FunktionalitĂ€ten, die im Kursverlauf bereits betrachtet wurden, immer im Hinblick darauf, dass viele der Merkmale, mit denen Sie bereits zu tun hatten, Objekte sind.

Vorkenntnisse: Grundlegende Computerkenntnisse, ein grundlegendes VerstĂ€ndnis von HTML und CSS, Vertrautheit mit  JavaScript Grundlagen (siehe Erste Schritte und Bausteine).
Ziel: VerstĂ€ndnis fĂŒr die grundlegende Theorie zur objektorientierten Programmierung, wie dies mit JavaScript zusammenhĂ€ngt  ("fast alle Dinge sind Objekte") und wie man mit JavaScript-Objekten zu arbeiten beginnt.

Objekt Grundlagen

Ein Objekt ist eine Sammlung von zusammenhĂ€ngenden Daten und/oder FunktionalitĂ€ten. Diese bestehen ĂŒblicherweise aus verschiedenen Variablen und Funktionen, die Eigenschaften und Methoden genannt werden, wenn sie sich innerhalb von Objekten befinden. Arbeiten wir ein Beispiel durch, um besser zu verstehen, wie ein Objekt aussieht.

FĂŒr den Anfang erzeugen wir eine lokale Kopie unserer Datei oojs.html. Sie enthĂ€lt nur sehr wenig -  ein <script> Element, um unseren Quelltext einzufĂŒgen. Wir werden diese Datei bzw. dieses Beispiel als Basis nutzen, um die grundlegende Objektsyntax zu erforschen. WĂ€hrend der Arbeit an diesem Beispiel sollten Sie ihre  developer tools JavaScript console (z.B. Browser-Entwicklerwerkzeuge) geöffnet haben und bereit sein, einige Befehle einzutippen.

Wie mit vielen Dingen in JavaScript beginnt das Erzeugen eines Objekts hĂ€ufig mit der Definition und Initialisierung einer Variablen. Versuchen Sie, folgendes unterhalb des bestehenden JavaScript Quelltextes einzugeben, dann abzuspeichern und einen Browser refresh durchzufĂŒhren:

var person = {};

Wenn Sie  person in ihrer JS console eingeben und die Entertaste drĂŒcken, sollten Sie folgendes Resultat erhalten:

[object Object]

GlĂŒckwunsch, Sie haben gerade ihr erstes Objekt erzeugt. Aufgabe erledigt! Aber dies ist ein leeres Objekt, also können wir noch nicht viel damit anfangen. Lassen sie uns unser Objekt erweitern, damit es folgendermaßen aussieht:

var person = {
  name: ['Bob', 'Smith'],
  age: 32,
  gender: 'male',
  interests: ['music', 'skiing'],
  bio: function() {
    alert(this.name[0] + ' ' + this.name[1] +
    ' is ' + this.age + ' years old. He likes ' +
    this.interests[0] + ' and ' + this.interests[1] + '.');
  },
  greeting: function() {
    alert('Hi! I\'m ' + this.name[0] + '.');
  }
};

Nach dem Abspeichern und Aktualisieren des Browsers versuchen Sie, etwas vom Folgenden in der JavaScript-Konsole ihrer Browser Entwicklerwerkzeuge einzugeben:

person.name
person.name[0]
person.age
person.interests[1]
person.bio()
person.greeting()

Sie haben nun einige Daten und Funktionen innerhalb ihres Objekts und sind in der Lage, mit recht einfacher Syntax darauf zuzugreifen!

Notiz: Wenn Sie Schwierigkeiten damit haben, dies zum Funktionieren zu bringen, versuchen Sie, Ihren Code mit unserer Version zu vergleichen - siehe  oojs-finished.html (zzgl. see it running live). Die Live Version wird eine leere Anzeige erzeugen - das ist so in Ordnung - öffnen Sie erneut die Entwicklerwerkzeuge [Mozilla Firefox: F12 -> Konsole] und versuchen Sie, die obigen Befehle einzugeben um die Objektstruktur zu betrachten.

Was passiert hier? Ein Objekt besteht aus vielen Elementen (engl. "Members", Anm. d. Übersetzers). Davon hat jedes einen Namen (z.B. name und age, wie oben) und einen Wert ( z.B. ['Bob', 'Smith' ] und 32). Jedes Name-Wert-Paar muss durch ein Komma getrennt sein und die jeweiligen Namen und Werte werden jeweils durch einen Doppelpunkt aufgeteilt. Die Syntax folgt stets diesem Muster:

var objectName = {
  member1Name: member1Value,
  member2Name: member2Value,
  member3Name: member3Value
};

Der Wert eines Objekt-Elements kann so ziemlich alles sein - in unserem person-Objekt haben wir einen String, eine Zahl, zwei Arrays und zwei Funktionen. Die ersten vier Elemente sind DatansÀtze und werden als Objekteigenschaften bezeichnet. Die letzten beiden Elemente sind Funktionen die es dem Objekt ermöglichen, etwas mit den Daten zu tun und werden als Methoden des Objekts bezeichnet.

Ein Objekt wie dieses bezeichnet man als Objektliteral — wir haben die Inhalte des Objekts wortwörtlich aufgeschrieben, als wir es erzeugt haben. Dies steht im Gegensatz zu solchen Objekten, die aus Klassen instanziert werden, welche wir spĂ€ter genauer betrachten werden.

Es ist durchaus ĂŒblich ein Objekt unter Verwendung eines Objektliterals zu erzeugen, wenn  man eine Reihe von strukturierten, zusammenhĂ€ngenden DatensĂ€tzen auf gewisse Weise ĂŒbertragen möchte. Zum Beispiel beim Senden einer Anfrage an einen Server, um diese in einer Datenbank abzuspeichern. Ein einzelnes Objekt zu senden ist viel effizienter, als viele DatensĂ€tze einzeln und darĂŒber hinaus ist es einfacher, mit einem Array zu arbeiten, wenn man einzelne DatensĂ€tze anhand ihres Namens identifizieren möchte.

Punktnotation

Oben haben Sie auf die Eigenschaften und Methoden des Objektes mittels Punktnotation zugegriffen. Der Objektbezeichner person dient als Namensraum - dieser muss zuerst angegeben werden, um auf etwas zuzugreifen, das innerhalb des Objektes eingekapselt ist. Als nĂ€chstes folgt der Punkt und anschließend der Bestandteil, auf den Sie zugreifen wollen - dies kann der Name einer einfachen Eigenschaft sein, ein Element einer Arrayeigenschaft oder der Aufruf einer der Objektmethoden, zum Beispiel:

person.age
person.interests[1]
person.bio()

Sub-NamensrÀume

Es ist sogar möglich, den Wert eines Objekt-Members zu einem anderen Objekt umzuwandeln.

Versuchen Sie zum Beispiel, den "name" Member von

name: ['Bob', 'Smith'],

zu

name : {
  first: 'Bob',
  last: 'Smith'
},

zu Ă€ndern. Hier erzeugen wir effektiv einen Sub-Namensraum. Das hört sich kompliziert an, ist es aber nicht - um auf diese Inhalte zuzugreifen, mĂŒssen Sie bloß den zusĂ€tzlichen Namensraum, getrennt durch einen Punkt, hinzufĂŒgen. Versuchen Sie folgendes in der JS Konsole:

person.name.first
person.name.last

Wichtig: An diesem Punkt mĂŒssen Sie ihre Methodendeklarationen umarbeiten und Instanzen von

name[0]
name[1]

zu

name.first
name.last

Ă€ndern. Sonst greifen die Methoden ins Leere.

Klammer-Notation

Es gibt einen weiteren Weg, auf Objekteigenschaften zuzugreifen - durch Benutzung der Klammern-Notation. Statt dies zu schreiben:

person.age
person.name.first

Schreibt man:

person['age']
person['name']['first']

Dies gleicht der Art wie man auf Arrayelemente zugreift und ist im Grunde der gleiche Vorgang - statt einen Index zu nutzen, um ein Element auszuwĂ€hlen, benutzt man den den Namen der mit jedem Memberwert assoziiert wird. Es wundert daher nicht, dass Objekte manchmal assoziative Arrays genannt werden - sie verknĂŒpfen Zeichenketten mit Werten in der gleichen Weise, wie ein Array Indizes mit Werten verknĂŒpft.

Wertzuweisungen an Objekt-Elemente

Bisher haben wir nur betrachtet, wie man Objekt-Elemente abruft ( getting ) — man kann den Wert von Objektelementen auch setzen ( updating ), indem man das Element, welches gesetzt werden soll, folgendermaßen deklariert:

person.age = 45;
person['name']['last'] = 'Cratchit';

Versuchen Sie, die Zeilen wie oben aufgefĂŒhrt einzugeben und dann die Elemente wieder abzurufen, etwa so:

person.age
person['name']['last']

Zuweisungen hören nicht beim Ändern von Werten existierender Eigenschaften und Methoden auf, man kann auch völlig neue Elemente erzeugen. Versuchen Sie dies in der JS Konsole:

person['eyes'] = 'hazel';
person.farewell = function() { alert("Bye everybody!"); }

Sie können diese neuen Elemente nun ausprobieren:

person['eyes']
person.farewell()

Ein nĂŒtzlicher Aspekt der Klammer-Notation ist jener, dass man nicht nur Elementwerte dynamisch zuweisen kann, sondern auch Elementnamen. Nehmen wir an, wir wollen es Usern ermöglichen, selbstdefinierte Wertetypen in ihren people-Daten zu speichern, indem sie den Elementnamen und Wert in zwei Textfeldern eingeben. Wir könnten diese Werte so abrufen:

var myDataName = nameInput.value;
var myDataValue = nameValue.value;

dann könnten wir diesen neuen Elementnamen und Wert zum person-Objekt so hinzufĂŒgen:

person[myDataName] = myDataValue;

Um das auszuprobieren, versuchen Sie, folgendes in ihren Quelltext einzufĂŒgen, gleich unterhalb der schliessenden, geschweiften Klammer des person-Objekts:

var myDataName = 'height';
var myDataValue = '1.75m';
person[myDataName] = myDataValue;

Nach dem Abspeichern und einem Browser-Refresh geben Sie folgendes in der Konsole ein:

person.height

Eine Eigenschaft zu einem Objekt hinzuzufĂŒgen ist mit der Punkt-Notation nicht möglich. Diese akzeptiert nur einen literalen Elementnamen, keine Variable, die auf einen Namen zeigt.

Was bedeutet "this"?

Sie haben vielleicht schon etwas seltsames in unseren Methoden bemerkt. Sehen wir uns zum Beispiel folgendes genauer an:

greeting: function() {
  alert('Hi! I\'m ' + this.name.first + '.');
}

Sie wundern sich wahrscheinlich, was dieses "this" sein soll. Das SchlĂŒsselwort this referenziert das derzeitige Objekt, in dem der Code hineingeschrieben wurde - in diesem Fall wĂ€re this gleichbedeutend mit person. Also warum nicht einfach stattdessen person schreiben? Wie Sie im Artikel  Object-oriented JavaScript for beginners sehen werden, wenn wir damit beginnen, z.B. Konstruktoren zu erzeugen usw.: this ist sehr nĂŒtzlich - es wird immer sicherstellen, dass die korrekten Werte verwendet werden, wenn sich der Kontext eines Elementes Ă€ndert (z.B. zwei unterschiedliche Objektinstanzen von person haben andere Namenswerte und sollten folgerichtig ihren jeweiligen Namenswert verwenden, wenn die greeting Methode aufgerufen wird).

Lassen Sie uns dies an einem vereinfachten Paar Objekten vom Typ person verdeutlichen:

var person1 = {
  name: 'Chris',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

var person2 = {
  name: 'Brian',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

In diesem Fall wird person1.greeting()  "Hi! I'm Chris." ausgeben; person2.greeting() wiederum wird  "Hi! I'm Brian." ausgeben, obwohl der Quelltext in jedem Fall genau gleich lautet. Wie schon gesagt,  this  ist gleichbedeutend mit dem Objekt, in dem sich der Quelltext befindet - das ist nicht sehr nĂŒtzlich, wenn man Objektliterale hĂ€ndisch schreibt, aber es ist sehr hilfreich, sobald Objekte dynamisch erzeugt werden (zum Beispiel unter Verwendung von Konstruktoren). Es wird im weiteren Verlauf alles deutlich werden.

Sie haben die ganze Zeit Objekte verwendet

Als Sie diese Beispiele durchgegangen sind, haben Sie wahrscheinlich gedacht, dass die Punktnotation, die Sie verwendet haben, sehr vertraut scheint. Es liegt daran, dass Sie diese im gesamten Kursverlauf benutzt haben. Jedes Mal, wenn wir ein Beispiel behandelten, welches Teile des built-in Browser API oder JavaScript-Objekte verwendete, haben wir Objekte verwendet, da solche FunktionalitÀten genau mit der gleichen Art von Objektstrukturen aufgebaut werden, wie wir sie hier betrachtet haben. Diese sind allerdings etwas komplexer als die unserer eigenen, einfachen Beispiele.

Wenn Sie String-Methoden wie diese verwenden,

myString.split(',');

haben Sie eine Methode verwendet, die eine Instanz der String-Klasse zur VerfĂŒgung stellte. Jedes Mal, wenn Sie einen String in ihrem Quelltext erstellen, wir dieser String automatisch als eine Instanz von String erzeugt, dadurch stehen einige allgemeine Methoden und Eigenschaften zur VerfĂŒgung.

Wenn Sie im DOM folgende Zeilen verwenden,

var myDiv = document.createElement('div');
var myVideo = document.querySelector('video');

haben Sie Methoden verwendet, die von einer Instanz der Klasse Document zur VerfĂŒgung gestellt wurden. FĂŒr jede geladene Webseite wird eine Instanz von Document erzeugt, die document genannt wird, welche die gesamte Struktur, den Inhalt und weitere Merkmale wie die URL reprĂ€sentiert. Dies bedeutet wiederum, dass einige allgemeine Methoden und Eigenschaften entsprechend verfĂŒgbar gemacht werden.

Das gleiche gilt fĂŒr so ziemlich jedes andere built-in Objekt/API, welches Sie benutzt haben  — z.B. Array, Math, usw.

Beachten Sie, dass built-in Objekte/APIs nicht zwangslĂ€ufig immer automatisch eine Objektinstanz erzeugen. Ein Beispiel, die  Notifications API — welche es modernen Browsern erlaubt, System Notifikationen zu generieren  — benötigt fĂŒr jede zu sendende Notifikation eine neue Objektinstanz, die Sie durch Verwendung des Konstruktors erzeugen mĂŒssen. Versuchen Sie, folgendes in Ihrer JavaScript Konsole einzugeben:

var myNotification = new Notification('Hello!');

Konstruktoren werden wir in einem spÀteren Artikel detaillierter behandeln.

Bemerkung: Es ist nĂŒtzlich, sich die Art, wie Objekte kommunizieren, als Nachrichtenweitergabe vorzustellen — wenn ein Objekt die AusfĂŒhrung einer Aktion von einem anderen Objekt benötigt, wird es meist eine Nachricht an dieses Objekt mittels einer seiner Methoden senden und auf eine Antwort warten, welche wir als RĂŒckgabewert bezeichnen.

Zusammenfassung

GlĂŒckwunsch, Sie haben das Ende unseres ersten JS Objekt Artikels erreicht —Sie sollten nun eine gute Vorstellung davon haben, wie man mit Objekten in JavaScript arbeitet — einschließlich der Erzeugung von eigenen, einfachen Objekte. Sie sollten auch zu schĂ€tzen wissen, dass Objekte als Daten- und Funktionsspeicherstrukturen sehr nĂŒtzlich sind — wenn Sie versuchen wĂŒrden, alle Eigenschaften und Methoden in unserem person-Objekt als einzelne Variablen bzw. Funktionen nachzuverfolgen, wĂ€re das sehr ineffizient und frustrierend und wir wĂŒrden riskieren, das gleichnamige Variablen kollidieren. Objekte lassen uns Informationen gefahrlos und sicher in ihrem jeweils eigenen Paket verstauen.

Im nÀchsten Artikel werden wir damit beginnen, uns die Theorie der objektorientierten Programmierung (OOP) anzusehen und wie solche Techniken in JavaScript umgesetzt werden können.

In diesem Modul