diff options
Diffstat (limited to 'files/de/learn/javascript/objects')
-rw-r--r-- | files/de/learn/javascript/objects/basics/index.html | 258 | ||||
-rw-r--r-- | files/de/learn/javascript/objects/index.html | 53 | ||||
-rw-r--r-- | files/de/learn/javascript/objects/inheritance/index.html | 440 | ||||
-rw-r--r-- | files/de/learn/javascript/objects/json/index.html | 345 | ||||
-rw-r--r-- | files/de/learn/javascript/objects/object-oriented_js/index.html | 290 | ||||
-rw-r--r-- | files/de/learn/javascript/objects/object_prototypes/index.html | 288 |
6 files changed, 1674 insertions, 0 deletions
diff --git a/files/de/learn/javascript/objects/basics/index.html b/files/de/learn/javascript/objects/basics/index.html new file mode 100644 index 0000000000..403f869034 --- /dev/null +++ b/files/de/learn/javascript/objects/basics/index.html @@ -0,0 +1,258 @@ +--- +title: JavaScript object basics +slug: Learn/JavaScript/Objects/Basics +translation_of: Learn/JavaScript/Objects/Basics +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">In diesem Artikel betrachten wir die fundamentale <strong>JavaScript Objekt Syntax</strong> 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.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Vorkenntnisse:</th> + <td>Grundlegende Computerkenntnisse, ein grundlegendes Verständnis von HTML und CSS, Vertrautheit mit JavaScript Grundlagen (siehe <a href="/en-US/docs/Learn/JavaScript/First_steps">Erste Schritte</a> und <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Bausteine</a>).</td> + </tr> + <tr> + <th scope="row">Ziel:</th> + <td>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.</td> + </tr> + </tbody> +</table> + +<h2 id="Objekt_Grundlagen">Objekt Grundlagen</h2> + +<p>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.</p> + +<p>Für den Anfang erzeugen wir eine lokale Kopie unserer Datei <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a>. Sie enthält nur sehr wenig - ein {{HTMLElement("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 <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools#The_JavaScript_console">developer tools JavaScript console</a> (z.B. Browser-Entwicklerwerkzeuge) geöffnet haben und bereit sein, einige Befehle einzutippen.</p> + +<p>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:</p> + +<pre class="brush: js notranslate">var person = {};</pre> + +<p>Wenn Sie <code>person</code> in ihrer JS console eingeben und die Entertaste drücken, sollten Sie folgendes Resultat erhalten:</p> + +<pre class="brush: js notranslate">[object Object]</pre> + +<p>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:</p> + +<pre class="brush: js notranslate">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] + '.'); + } +}; +</pre> + +<p>Nach dem Abspeichern und Aktualisieren des Browsers versuchen Sie, etwas vom Folgenden in der JavaScript-Konsole ihrer Browser Entwicklerwerkzeuge einzugeben:</p> + +<pre class="brush: js notranslate">person.name +person.name[0] +person.age +person.interests[1] +person.bio() +person.greeting()</pre> + +<p>Sie haben nun einige Daten und Funktionen innerhalb ihres Objekts und sind in der Lage, mit recht einfacher Syntax darauf zuzugreifen!</p> + +<div class="note"> +<p><strong>Notiz</strong>: Wenn Sie Schwierigkeiten damit haben, dies zum Funktionieren zu bringen, versuchen Sie, Ihren Code mit unserer Version zu vergleichen - siehe <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (zzgl. <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">see it running live</a>). 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.</p> +</div> + +<p>Was passiert hier? Ein Objekt besteht aus vielen Elementen (engl. "Members", Anm. d. Übersetzers). Davon hat jedes einen Namen (z.B. <code>name</code> und <code>age</code>, wie oben) und einen Wert ( z.B. <code>['Bob', 'Smith' ]</code> und <code>32</code>). 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:</p> + +<pre class="brush: js notranslate">var objectName = { + member1Name: member1Value, + member2Name: member2Value, + member3Name: member3Value +};</pre> + +<p>Der Wert eines Objekt-Elements kann so ziemlich alles sein - in unserem <code>person</code>-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 <strong>Methoden</strong> des Objekts bezeichnet.</p> + +<p>Ein Objekt wie dieses bezeichnet man als <strong>Objektliteral</strong> — 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.</p> + +<p>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.</p> + +<h2 id="Punktnotation">Punktnotation</h2> + +<p>Oben haben Sie auf die Eigenschaften und Methoden des Objektes mittels Punktnotation zugegriffen.<strong> </strong>Der Objektbezeichner <code>person</code> dient als <strong>Namensraum </strong>- dieser muss zuerst angegeben werden, um auf etwas zuzugreifen, das innerhalb des Objektes <strong>eingekapselt </strong>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 <strong>Objektmethoden</strong>, zum Beispiel:</p> + +<pre class="brush: js notranslate">person.age +person.interests[1] +person.bio()</pre> + +<h3 id="Sub-Namensräume">Sub-Namensräume</h3> + +<p>Es ist sogar möglich, den Wert eines Objekt-Members zu einem anderen Objekt umzuwandeln.</p> + +<p>Versuchen Sie zum Beispiel, den "name" Member von</p> + +<pre class="brush: js notranslate">name: ['Bob', 'Smith'],</pre> + +<p>zu</p> + +<pre class="brush: js notranslate">name : { + first: 'Bob', + last: 'Smith' +},</pre> + +<p>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:</p> + +<pre class="brush: js notranslate">person.name.first +person.name.last</pre> + +<p><strong>Wichtig</strong>: An diesem Punkt müssen Sie ihre Methodendeklarationen umarbeiten und Instanzen von</p> + +<pre class="brush: js notranslate">name[0] +name[1]</pre> + +<p>zu</p> + +<pre class="brush: js notranslate">name.first +name.last</pre> + +<p>ändern. Sonst greifen die Methoden ins Leere.</p> + +<h2 id="Klammer-Notation">Klammer-Notation</h2> + +<p>Es gibt einen weiteren Weg, auf Objekteigenschaften zuzugreifen - durch Benutzung der Klammern-Notation. Statt dies zu schreiben:</p> + +<pre class="brush: js notranslate">person.age +person.name.first</pre> + +<p>Schreibt man:</p> + +<pre class="brush: js notranslate">person['age'] +person['name']['first']</pre> + +<p>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 <strong>assoziative Arrays</strong> genannt werden - sie verknüpfen Zeichenketten mit Werten in der gleichen Weise, wie ein Array Indizes mit Werten verknüpft.</p> + +<h2 id="Wertzuweisungen_an_Objekt-Elemente">Wertzuweisungen an Objekt-Elemente</h2> + +<p>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:</p> + +<pre class="brush: js notranslate">person.age = 45; +person['name']['last'] = 'Cratchit';</pre> + +<p>Versuchen Sie, die Zeilen wie oben aufgeführt einzugeben und dann die Elemente wieder abzurufen, etwa so:</p> + +<pre class="brush: js notranslate">person.age +person['name']['last']</pre> + +<p>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:</p> + +<pre class="brush: js notranslate">person['eyes'] = 'hazel'; +person.farewell = function() { alert("Bye everybody!"); }</pre> + +<p>Sie können diese neuen Elemente nun ausprobieren:</p> + +<pre class="brush: js notranslate">person['eyes'] +person.farewell()</pre> + +<p>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 <code>people</code>-Daten zu speichern, indem sie den Elementnamen und Wert in zwei Textfeldern eingeben. Wir könnten diese Werte so abrufen:</p> + +<pre class="brush: js notranslate">var myDataName = nameInput.value; +var myDataValue = nameValue.value;</pre> + +<p>dann könnten wir diesen neuen Elementnamen und Wert zum <code>person</code>-Objekt so hinzufügen:</p> + +<pre class="brush: js notranslate">person[myDataName] = myDataValue;</pre> + +<p>Um das auszuprobieren, versuchen Sie, folgendes in ihren Quelltext einzufügen, gleich unterhalb der schliessenden, geschweiften Klammer des <code>person</code>-Objekts:</p> + +<pre class="brush: js notranslate">var myDataName = 'height'; +var myDataValue = '1.75m'; +person[myDataName] = myDataValue;</pre> + +<p>Nach dem Abspeichern und einem Browser-Refresh geben Sie folgendes in der Konsole ein:</p> + +<pre class="brush: js notranslate">person.height</pre> + +<p>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.</p> + +<h2 id="Was_bedeutet_this">Was bedeutet "this"?</h2> + +<p>Sie haben vielleicht schon etwas seltsames in unseren Methoden bemerkt. Sehen wir uns zum Beispiel folgendes genauer an:</p> + +<pre class="brush: js notranslate">greeting: function() { + alert('Hi! I\'m ' + this.name.first + '.'); +}</pre> + +<p>Sie wundern sich wahrscheinlich, was dieses "this" sein soll. Das Schlüsselwort <code>this</code> referenziert das derzeitige Objekt, in dem der Code hineingeschrieben wurde - in diesem Fall wäre <code>this</code> gleichbedeutend mit <code>person</code>. Also warum nicht einfach stattdessen <code>person</code> schreiben? Wie Sie im Artikel <a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a> sehen werden, wenn wir damit beginnen, z.B. Konstruktoren zu erzeugen usw.: <code>this</code> 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 <code>person</code> haben andere Namenswerte und sollten folgerichtig ihren jeweiligen Namenswert verwenden, wenn die greeting Methode aufgerufen wird).</p> + +<p>Lassen Sie uns dies an einem vereinfachten Paar Objekten vom Typ <code>person</code> verdeutlichen:</p> + +<pre class="brush: js notranslate">var person1 = { + name: 'Chris', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +var person2 = { + name: 'Brian', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p>In diesem Fall wird <code>person1.greeting()</code> "Hi! I'm Chris." ausgeben; <code>person2.greeting()</code> wiederum wird "Hi! I'm Brian." ausgeben, obwohl der Quelltext in jedem Fall genau gleich lautet. Wie schon gesagt, <code>this</code> 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.</p> + +<h2 id="Sie_haben_die_ganze_Zeit_Objekte_verwendet">Sie haben die ganze Zeit Objekte verwendet</h2> + +<p>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.</p> + +<p>Wenn Sie String-Methoden wie diese verwenden,</p> + +<pre class="brush: js notranslate">myString.split(',');</pre> + +<p>haben Sie eine Methode verwendet, die eine Instanz der <code>String</code>-Klasse zur Verfügung stellte. Jedes Mal, wenn Sie einen String in ihrem Quelltext erstellen, wir dieser String automatisch als eine Instanz von <code>String</code> erzeugt, dadurch stehen einige allgemeine Methoden und Eigenschaften zur Verfügung.</p> + +<p>Wenn Sie im DOM folgende Zeilen verwenden,</p> + +<pre class="brush: js notranslate">var myDiv = document.createElement('div'); +var myVideo = document.querySelector('video');</pre> + +<p>haben Sie Methoden verwendet, die von einer Instanz der Klasse <code><a href="/en-US/docs/Web/API/Document">Document</a></code> zur Verfügung gestellt wurden. Für jede geladene Webseite wird eine Instanz von <code>Document</code> erzeugt, die <code>document</code> 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.</p> + +<p>Das gleiche gilt für so ziemlich jedes andere built-in Objekt/API, welches Sie benutzt haben — z.B. <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code>, usw.</p> + +<p>Beachten Sie, dass built-in Objekte/APIs nicht zwangsläufig immer automatisch eine Objektinstanz erzeugen. Ein Beispiel, die <a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a> — 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:</p> + +<pre class="brush: js notranslate">var myNotification = new Notification('Hello!');</pre> + +<p>Konstruktoren werden wir in einem späteren Artikel detaillierter behandeln.</p> + +<div class="note"> +<p><strong>Bemerkung</strong>: Es ist nützlich, sich die Art, wie Objekte kommunizieren, als <strong>Nachrichtenweitergabe</strong> 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.</p> +</div> + +<h2 id="Zusammenfassung">Zusammenfassung</h2> + +<p>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 <code>person</code>-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.</p> + +<p>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.</p> + +<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_diesem_Modul">In diesem Modul</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Objekt Grundlagen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Objektorientiertes JavaScript für Anfänger</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Objekt Prototypen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Vererbung in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Mit JSON Daten arbeiten</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Objekterstellungsübungen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Funktionalität zu unserer Hüpfball Demo hinzufügen</a></li> +</ul> diff --git a/files/de/learn/javascript/objects/index.html b/files/de/learn/javascript/objects/index.html new file mode 100644 index 0000000000..9178a14f6d --- /dev/null +++ b/files/de/learn/javascript/objects/index.html @@ -0,0 +1,53 @@ +--- +title: Introducing JavaScript objects +slug: Learn/JavaScript/Objects +tags: + - Beginner + - Guide + - JavaScript + - Objects + - Objekte + - Programmieren + - Prototypes + - Tutorial +translation_of: Learn/JavaScript/Objects +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">In JavaScript sind die meisten Dinge Objekte die auf dem Grundstein von JavaScript aufgebaut worden sind. Hierzu zählen Strings, Arrays welche mittels der API grundlegend fundamentiert sind. Du kannst auch deine eigenen Objekte definieren um Dinge aus der Realität in Programmcode wiederzuverwenden. Die objektorientierte Programmierung ist wichtig um ein komplettes Verständnis zu bekommen als auch die Sprache wirklich zu verstehen. Aus diesem Grund stellen wir euch einige Lernmodule an um besser in das Thema einsteigen zu können.<br> + <br> + Aber hier wollen wir euch erstmal erklären, was ein Objekt genau ist und wie die Syntax für eine Definition eines Objektes ist.</p> + +<h2 id="Voraussetzungen">Voraussetzungen</h2> + +<p>Bevor du mit diesem Lernmodul beginnst, solltest du dich mit HTML und CSS vertraut gemacht haben. Solltest du noch keine Vorkenntnisse haben, so sehe dir bitte <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Introduction">Einführung in HTML</a> und <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS">Einführung in CSS</a> an bevor du mit JavaScript beginnst.</p> + +<p>Auch solltest du dich vorher mit den Grundlagen von JavaScript vertraut gemacht haben, sie dazu bitte in folgenden Modulen nach: <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript: Erste Schritte</a> und <a href="/en-US/docs/Learn/JavaScript/Building_blocks">JavaScript: Elementare Grundlagen</a>.</p> + +<div class="note"> +<p><strong>Hinweis</strong>: Solltest du an einem Computer arbeiten, der dir das Erstellen und Bearbeiten von Dateien nicht erlaubt, so kannst du Dienste wie <a href="http://jsbin.com/">JSBin</a> oder <a href="https://thimble.mozilla.org/">Thimble</a> für diesen Kurs nutzen.</p> +</div> + +<h2 id="Guides">Guides</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Objekt Grundlagen</a></dt> + <dd>In diesem ersten Kaptiel erklären wir euch wie ein Objekt fundamental aufgebaut ist, als auch die Syntax zu diesem. Wir behandeln außerdem einige Gebiete, die wir schon bereits gesehen haben, denn die meisten Dinge in JavaScript mit denen du arbeiten wirst sind Objekte.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Objektorientiertes JavaScript für Anfänger</a></dt> + <dd>Hier zeigen wir euch die objektorientierte Programmierung (OOP/OOJS) - hier gibt es erste Einblicke wie du dein Objekt am besten definierst und dann zeigen wir dir, wie JavaScript dein Objekt zum Leben bringt durch Instanziierung.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Objekt Prototypes</a></dt> + <dd>Prototypes ist der Begriff für den Vorgang für die weitergehende Verwendung eines Objektes mit vererbbaren Funktionen. Solltest du bereits eine andere objektorientierte Programmiersprache benutzt haben, wirst du merken, dass JavaScript anders funktioniert. In dem Modul behandeln wir außerdem wie die Verkettung von Prototypen funktioniert und schauen uns die <em>Eigenschaften eines Objektes</em> genauer an, mit denen wir auch die Funktionen definieren werden.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Vererbung in JavaScript</a></dt> + <dd>Nachdem du in den vorherigen Lernmodulen einiges über OOJS gelernt hast, zeigen wir dir hier wie du Funktionen und Eigenschaften mit einem anderen Objekt vererbben kannst.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Arbeiten mit JSON Strukturen</a></dt> + <dd>JavaScript Object Notation (JSON) ist eine textbasierte Struktursprache um Daten kompakt und wiederverwendbar zu machen. Diese Struktursprache ist die gängigste in JavaScript um Objekte zu beschreiben, speichern oder für andere Dienste verfügbar zu machen.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Objekte an einer Übung definieren</a></dt> + <dd>In dieser Übung möchten wir nochmal alle vorherigen Themen aufgreifen und nochmal mit der Syntax von Objekten üben und dabei etwas Spaß mit springenden, bunten Bällen haben.</dd> +</dl> + +<h2 id="Übungen">Übungen</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Erstelle neue Funktionen für springende Bälle</a></dt> + <dd>In dieser Übung greifen wir uns das Demo-Projekt aus dem vorherigen Artikel nochmal auf und werden die springenden Bälle mit neuen Objektfunktionen erweitern.</dd> +</dl> diff --git a/files/de/learn/javascript/objects/inheritance/index.html b/files/de/learn/javascript/objects/inheritance/index.html new file mode 100644 index 0000000000..827dda17f6 --- /dev/null +++ b/files/de/learn/javascript/objects/inheritance/index.html @@ -0,0 +1,440 @@ +--- +title: Inheritance in JavaScript +slug: Learn/JavaScript/Objects/Inheritance +translation_of: Learn/JavaScript/Objects/Inheritance +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Nachdem nun die schmutzigen Details des OOJS erklärt sind, beschäftigt sich dieser Artikel damit, wie "Kinder"-Objektklassen (Konstruktoren) Features von ihren "Eltern"-Klassen vererbt bekommen. Zusätzlich stellen wir Hinweise dazu bereit, wann und wo Du OOJS am besten anwendest und wie mit Klassen im modern ECMAScript Syntax umgegangen wird.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Voraussetzungen:</th> + <td>Grundsätzliche EDV-Kenntnisse, ein grundlegendes Verständnis für HTML und CSS, mit JavaScript Grundlagen vertraut sein (siehe <a href="https://wiki.developer.mozilla.org/de/docs/Learn/JavaScript/First_steps">Erste Schritte</a> und <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) und Grundlagen zu OOJS (siehe<a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> + </tr> + <tr> + <th scope="row">Lernziel:</th> + <td>Zu verstehen, wie es in JavaScript möglich ist, Vererbung zu implementieren.</td> + </tr> + </tbody> +</table> + +<h2 id="Prototypal_inheritance">Prototypal inheritance</h2> + +<p>So far we have seen some inheritance in action — we have seen how prototype chains work, and how members are inherited going up a chain. But mostly this has involved built-in browser functions. How do we create an object in JavaScript that inherits from another object?</p> + +<p>Let's explore how to do this with a concrete example.</p> + +<h2 id="Getting_started">Getting started</h2> + +<p>First of all, make yourself a local copy of our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> file (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">running live</a> also). Inside here you'll find the same <code>Person()</code> constructor example that we've been using all the way through the module, with a slight difference — we've defined only the properties inside the constructor:</p> + +<pre class="brush: js notranslate">function Person(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; +};</pre> + +<p>The methods are <em>all</em> defined on the constructor's prototype. For example:</p> + +<pre class="brush: js notranslate">Person.prototype.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); +};</pre> + +<div class="note"> +<p><strong>Note</strong>: In the source code, you'll also see <code>bio()</code> and <code>farewell()</code> methods defined. Later you'll see how these can be inherited by other constructors.</p> +</div> + +<p>Say we wanted to create a <code>Teacher</code> class, like the one we described in our initial object-oriented definition, which inherits all the members from <code>Person</code>, but also includes:</p> + +<ol> + <li>A new property, <code>subject</code> — this will contain the subject the teacher teaches.</li> + <li>An updated <code>greeting()</code> method, which sounds a bit more formal than the standard <code>greeting()</code> method — more suitable for a teacher addressing some students at school.</li> +</ol> + +<h2 id="Defining_a_Teacher_constructor_function">Defining a Teacher() constructor function</h2> + +<p>The first thing we need to do is create a <code>Teacher()</code> constructor — add the following below the existing code:</p> + +<pre class="brush: js notranslate">function Teacher(first, last, age, gender, interests, subject) { + Person.call(this, first, last, age, gender, interests); + + this.subject = subject; +}</pre> + +<p>This looks similar to the Person constructor in many ways, but there is something strange here that we've not seen before — the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code> function. This function basically allows you to call a function defined somewhere else, but in the current context. The first parameter specifies the value of <code>this</code> that you want to use when running the function, and the other parameters are those that should be passed to the function when it is invoked.</p> + +<p>We want the <code>Teacher()</code> constructor to take the same parameters as the <code>Person()</code> constructor it is inheriting from, so we specify them all as parameters in the <code>call()</code> invocation.</p> + +<p>The last line inside the constructor simply defines the new <code>subject</code> property that teachers are going to have, which generic people don't have.</p> + +<p>As a note, we could have simply done this:</p> + +<pre class="brush: js notranslate">function Teacher(first, last, age, gender, interests, subject) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.subject = subject; +}</pre> + +<p>But this is just redefining the properties anew, not inheriting them from <code>Person()</code>, so it defeats the point of what we are trying to do. It also takes more lines of code.</p> + +<h3 id="Inheriting_from_a_constructor_with_no_parameters">Inheriting from a constructor with no parameters</h3> + +<p>Note that if the constructor you are inheriting from doesn't take its property values from parameters, you don't need to specify them as additional arguments in <code>call()</code>. So, for example, if you had something really simple like this:</p> + +<pre class="brush: js notranslate">function Brick() { + this.width = 10; + this.height = 20; +}</pre> + +<p>You could inherit the <code>width</code> and <code>height</code> properties by doing this (as well as the other steps described below, of course):</p> + +<pre class="brush: js notranslate">function BlueGlassBrick() { + Brick.call(this); + + this.opacity = 0.5; + this.color = 'blue'; +}</pre> + +<p>Note that we've only specified <code>this</code> inside <code>call()</code> — no other parameters are required as we are not inheriting any properties from the parent that are set via parameters.</p> + +<h2 id="Setting_Teachers_prototype_and_constructor_reference">Setting Teacher()'s prototype and constructor reference</h2> + +<p>All is good so far, but we have a problem. We have defined a new constructor, and it has a <code>prototype</code> property, which by default just contains an object with a reference to the constructor function itself. It does not contain the methods of the Person constructor's <code>prototype</code> property. To see this, enter <code>Object.getOwnPropertyNames(Teacher.prototype)</code> into either the text input field or your JavaScript console. Then enter it again, replacing <code>Teacher</code> with <code>Person</code>. Nor does the new constructor <em>inherit</em> those methods. To see this, compare the outputs of <code>Person.prototype.greeting</code> and <code>Teacher.prototype.greeting</code>. We need to get <code>Teacher()</code> to inherit the methods defined on <code>Person()</code>'s prototype. So how do we do that?</p> + +<ol> + <li>Add the following line below your previous addition: + <pre class="brush: js notranslate">Teacher.prototype = Object.create(Person.prototype);</pre> + Here our friend <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> comes to the rescue again. In this case we are using it to create a new object and make it the value of <code>Teacher.prototype</code>. The new object has <code>Person.prototype</code> as its prototype and will therefore inherit, if and when needed, all the methods available on <code>Person.prototype</code>.</li> + <li>We need to do one more thing before we move on. After adding the last line, <code>Teacher.</code><code>prototype</code>'s <code>constructor</code> property is now equal to <code>Person()</code>, because we just set <code>Teacher.prototype</code> to reference an object that inherits its properties from <code>Person.prototype</code>! Try saving your code, loading the page in a browser, and entering <code>Teacher.prototype.constructor</code> into the console to verify.</li> + <li>This can become a problem, so we need to set this right. You can do so by going back to your source code and adding the following line at the bottom: + <pre class="brush: js notranslate">Object.defineProperty(Teacher.prototype, 'constructor', { + value: Teacher, + enumerable: false, // so that it does not appear in 'for in' loop + writable: true });</pre> + </li> + <li>Now if you save and refresh, entering <code>Teacher.prototype.constructor</code> should return <code>Teacher()</code>, as desired, plus we are now inheriting from <code>Person()</code>!</li> +</ol> + +<h2 id="Giving_Teacher_a_new_greeting_function">Giving Teacher() a new greeting() function</h2> + +<p>To finish off our code, we need to define a new <code>greeting()</code> function on the <code>Teacher()</code> constructor.</p> + +<p>The easiest way to do this is to define it on <code>Teacher()</code>'s prototype — add the following at the bottom of your code:</p> + +<pre class="brush: js notranslate">Teacher.prototype.greeting = function() { + let prefix; + + if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') { + prefix = 'Mr.'; + } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') { + prefix = 'Ms.'; + } else { + prefix = 'Mx.'; + } + + alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); +};</pre> + +<p>This alerts the teacher's greeting, which also uses an appropriate name prefix for their gender, worked out using a conditional statement.</p> + +<h2 id="Trying_the_example_out">Trying the example out</h2> + +<p>Now that you've entered all the code, try creating an object instance from <code>Teacher()</code> by putting the following at the bottom of your JavaScript (or something similar of your choosing):</p> + +<pre class="brush: js notranslate">let teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre> + +<p>Now save and refresh, and try accessing the properties and methods of your new <code>teacher1</code> object, for example:</p> + +<pre class="brush: js notranslate">teacher1.name.first; +teacher1.interests[0]; +teacher1.bio(); +teacher1.subject; +teacher1.greeting(); +teacher1.farewell();</pre> + +<p>These should all work just fine. The queries on lines 1, 2, 3, and 6 access members inherited from the generic <code>Person()</code> constructor (class). The query on line 4 accesses a member that is available only on the more specialized <code>Teacher()</code> constructor (class). The query on line 5 would have accessed a member inherited from <code>Person()</code>, except for the fact that <code>Teacher()</code> has its own member with the same name, so the query accesses that member.</p> + +<div class="note"> +<p><strong>Note</strong>: If you have trouble getting this to work, compare your code to our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">finished version</a> (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">running live</a> also).</p> +</div> + +<p>The technique we covered here is not the only way to create inheriting classes in JavaScript, but it works OK, and it gives you a good idea about how to implement inheritance in JavaScript.</p> + +<p>You might also be interested in checking out some of the new {{glossary("ECMAScript")}} features that allow us to do inheritance more cleanly in JavaScript (see <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). We didn't cover those here, as they are not yet supported very widely across browsers. All the other code constructs we discussed in this set of articles are supported as far back as IE9 or earlier, and there are ways to achieve earlier support than that.</p> + +<p>A common way is to use a JavaScript library — most of the popular options have an easy set of functionality available for doing inheritance more easily and quickly. <a href="http://coffeescript.org/#classes">CoffeeScript</a> for example provides <code>class</code>, <code>extends</code>, etc.</p> + +<h2 id="A_further_exercise">A further exercise</h2> + +<p>In our <a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">OOP theory section</a>, we also included a <code>Student</code> class as a concept, which inherits all the features of <code>Person</code>, and also has a different <code>greeting()</code> method from <code>Person</code> that is much more informal than the <code>Teacher</code>'s greeting. Have a look at what the student's greeting looks like in that section, and try implementing your own <code>Student()</code> constructor that inherits all the features of <code>Person()</code>, and implements the different <code>greeting()</code> function.</p> + +<div class="note"> +<p><strong>Note</strong>: If you have trouble getting this to work, have a look at our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">finished version</a> (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">running live</a> also).</p> +</div> + +<h2 id="Object_member_summary">Object member summary</h2> + +<p>To summarize, you've got four types of property/method to worry about:</p> + +<ol> + <li>Those defined inside a constructor function that are given to object instances. These are fairly easy to spot — in your own custom code, they are the members defined inside a constructor using the <code>this.x = x</code> type lines; in built in browser code, they are the members only available to object instances (usually created by calling a constructor using the <code>new</code> keyword, e.g. <code>let myInstance = new myConstructor()</code>).</li> + <li>Those defined directly on the constructor themselves, that are available only on the constructor. These are commonly only available on built-in browser objects, and are recognized by being chained directly onto a constructor, <em>not</em> an instance. For example, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>. These are also known as <strong>static properties/methods</strong>.</li> + <li>Those defined on a constructor's prototype, which are inherited by all instances and inheriting object classes. These include any member defined on a Constructor's <code>prototype</code> property, e.g. <code>myConstructor.prototype.x()</code>.</li> + <li>Those available on an object instance, which can either be an object created when a constructor is instantiated like we saw above (so for example <code>var teacher1 = new Teacher( name = 'Chris' );</code> and then <code>teacher1.name</code>), or an object literal (<code>let teacher1 = { name = 'Chris' }</code> and then <code>teacher1.name</code>).</li> +</ol> + +<p>If you are not sure which is which, don't worry about it just yet — you are still learning, and familiarity will come with practice.</p> + +<h2 id="ECMAScript_2015_Classes">ECMAScript 2015 Classes</h2> + +<p>ECMAScript 2015 introduces <a href="/en-US/docs/Web/JavaScript/Reference/Classes">class syntax</a> to JavaScript as a way to write reusable classes using easier, cleaner syntax, which is more similar to classes in C++ or Java. In this section we'll convert the Person and Teacher examples from prototypal inheritance to classes, to show you how it's done.</p> + +<div class="note"> +<p><strong>Note</strong>: This modern way of writing classes is supported in all modern browsers, but it is still worth knowing about the underlying prototypal inheritance in case you work on a project that requires supporting a browser that doesn't support this syntax (most notably Internet Explorer).</p> +</div> + +<p>Let's look at a rewritten version of the Person example, class-style:</p> + +<pre class="brush: js notranslate">class Person { + constructor(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + } + + greeting() { + console.log(`Hi! I'm ${this.name.first}`); + }; + + farewell() { + console.log(`${this.name.first} has left the building. Bye for now!`); + }; +} +</pre> + +<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">class</a> statement indicates that we are creating a new class. Inside this block, we define all the features of the class:</p> + +<ul> + <li>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/constructor">constructor()</a></code> method defines the constructor function that represents our <code>Person</code> class.</li> + <li><code>greeting()</code> and <code>farewell()</code> are class methods. Any methods you want associated with the class are defined inside it, after the constructor. In this example, we've used <a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">template literals</a> rather than string concatenation to make the code easier to read.</li> +</ul> + +<p>We can now instantiate object instances using the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> operator</a>, in just the same way as we did before:</p> + +<pre class="brush: js notranslate">let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']); +han.greeting(); +// Hi! I'm Han + +let leia = new Person('Leia', 'Organa', 19, 'female', ['Government']); +leia.farewell(); +// Leia has left the building. Bye for now +</pre> + +<div class="note"> +<p><strong>Note</strong>: Under the hood, your classes are being converted into Prototypal Inheritance models — this is just syntactic sugar. But I'm sure you'll agree that it's easier to write.</p> +</div> + +<h3 id="Inheritance_with_class_syntax">Inheritance with class syntax</h3> + +<p>Above we created a class to represent a person. They have a series of attributes that are common to all people; in this section we'll create our specialized <code>Teacher</code> class, making it inherit from <code>Person</code> using modern class syntax. This is called creating a subclass or subclassing.</p> + +<p>To create a subclass we use the <a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends keyword</a> to tell JavaScript the class we want to base our class on,</p> + +<pre class="brush: js notranslate">class Teacher extends Person { + constructor(subject, grade) { + this.subject = subject; + this.grade = grade; + } +}</pre> + +<p>but there's a little catch.</p> + +<p>Unlike old-school constructor functions where the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> operator</a> does the initialization of <code>this</code> to a newly-allocated object, this isn't automatically initialized for a class defined by the <a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends</a> keyword, i.e the sub-classes.</p> + +<p>Therefore running the above code will give an error:</p> + +<pre class="brush: js notranslate">Uncaught ReferenceError: Must call super constructor in derived class before +accessing 'this' or returning from derived constructor</pre> + +<p>For sub-classes, the <code>this</code> intialization to a newly allocated object is always dependant on the parent class constructor, i.e the constructor function of the class from which you're extending.</p> + +<p>Here we are extending the <code>Person</code> class — the <code>Teacher</code> sub-class is an extension of the <code>Person</code> class. So for <code>Teacher</code>, the <code>this</code> initialization is done by the <code>Person</code> constructor.</p> + +<p>To call the parent constructor we have to use the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> operator</a>, like so:</p> + +<pre class="brush: js notranslate">class Teacher extends Person { + constructor(subject, grade) { + super(); // Now 'this' is initialized by calling the parent constructor. + this.subject = subject; + this.grade = grade; + } +}</pre> + +<p>There is no point having a sub-class if it doesn't inherit properties from the parent class.<br> + It is good then, that the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> operator</a> also accepts arguments for the parent constructor.</p> + +<p>Looking back to our <code>Person</code> constructor, we can see it has the following block of code in its constructor method:</p> + +<pre class="brush: js notranslate"> constructor(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; +} </pre> + +<p>Since the <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/super">super()</a></code> operator is actually the parent class constructor, passing it the necessary arguments of the <code>Parent</code> class constructor will also initialize the parent class properties in our sub-class, thereby inheriting it:</p> + +<pre class="brush: js notranslate">class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + super(first, last, age, gender, interests); + + // subject and grade are specific to Teacher + this.subject = subject; + this.grade = grade; + } +} +</pre> + +<p>Now when we instantiate <code>Teacher</code> object instances, we can call methods and properties defined on both <code>Teacher</code>and <code>Person</code> as we'd expect:</p> + +<pre class="brush: js notranslate">let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5); +snape.greeting(); // Hi! I'm Severus. +snape.farewell(); // Severus has left the building. Bye for now. +snape.age // 58 +snape.subject; // Dark arts +</pre> + +<p>Like we did with Teachers, we could create other subclasses of <code>Person</code> to make them more specialized without modifying the base class.</p> + +<div class="note"> +<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-class-inheritance.html">es2015-class-inheritance.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-class-inheritance.html">see it live also</a>).</p> +</div> + +<h2 id="Getters_and_Setters">Getters and Setters</h2> + +<p>There may be times when we want to change the values of an attribute in the classes we create or we don't know what the final value of an attribute will be. Using the <code>Teacher</code> example, we may not know what subject the teacher will teach before we create them, or their subject may change between terms.</p> + +<p>We can handle such situations with getters and setters.</p> + +<p>Let's enhance the Teacher class with getters and setters. The class starts the same as it was the last time we looked at it.</p> + +<p>Getters and setters work in pairs. A getter returns the current value of the variable and its corresponding setter changes the value of the variable to the one it defines.</p> + +<p>The modified <code>Teacher</code> class looks like this:</p> + +<pre class="brush: js notranslate">class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + super(first, last, age, gender, interests); + // subject and grade are specific to Teacher + this._subject = subject; + this.grade = grade; + } + + get subject() { + return this._subject; + } + + set subject(newSubject) { + this._subject = newSubject; + } +} +</pre> + +<p>In our class above we have a getter and setter for the <code>subject</code> property. We use <strong><code>_</code> </strong> to create a separate value in which to store our name property. Without using this convention, we would get errors every time we called get or set. At this point:</p> + +<ul> + <li>To show the current value of the <code>_subject</code> property of the <code>snape</code> object we can use the <code>snape.subject</code> getter method.</li> + <li>To assign a new value to the <code>_subject</code> property we can use the <code>snape.subject="new value"</code> setter method.</li> +</ul> + +<p>The example below shows the two features in action:</p> + +<pre class="brush: js notranslate">// Check the default value +console.log(snape.subject) // Returns "Dark arts" + +// Change the value +snape.subject = "Balloon animals" // Sets _subject to "Balloon animals" + +// Check it again and see if it matches the new value +console.log(snape.subject) // Returns "Balloon animals" +</pre> + +<div class="note"> +<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-getters-setters.html">es2015-getters-setters.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-getters-setters.html">see it live also</a>).</p> +</div> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> Getters and setters can be very useful at times, for example when you want to run some code every time a property is requested or set. For simple cases, however, plain property access without a getter or setter will do just fine.</p> +</div> + +<h2 id="When_would_you_use_inheritance_in_JavaScript">When would you use inheritance in JavaScript?</h2> + +<p>Particularly after this last article, you might be thinking "woo, this is complicated". Well, you are right. Prototypes and inheritance represent some of the most complex aspects of JavaScript, but a lot of JavaScript's power and flexibility comes from its object structure and inheritance, and it is worth understanding how it works.</p> + +<p>In a way, you use inheritance all the time. Whenever you use various features of a Web API , or methods/properties defined on a built-in browser object that you call on your strings, arrays, etc., you are implicitly using inheritance.</p> + +<p>In terms of using inheritance in your own code, you probably won't use it often, especially to begin with, and in small projects. It is a waste of time to use objects and inheritance just for the sake of it when you don't need them. But as your code bases get larger, you are more likely to find a need for it. If you find yourself starting to create a number of objects that have similar features, then creating a generic object type to contain all the shared functionality and inheriting those features in more specialized object types can be convenient and useful.</p> + +<div class="note"> +<p><strong>Note</strong>: Because of the way JavaScript works, with the prototype chain, etc., the sharing of functionality between objects is often called <strong>delegation</strong>. Specialized objects delegate functionality to a generic object type.</p> +</div> + +<p>When using inheritance, you are advised to not have too many levels of inheritance, and to keep careful track of where you define your methods and properties. It is possible to start writing code that temporarily modifies the prototypes of built-in browser objects, but you should not do this unless you have a really good reason. Too much inheritance can lead to endless confusion, and endless pain when you try to debug such code.</p> + +<p>Ultimately, objects are just another form of code reuse, like functions or loops, with their own specific roles and advantages. If you find yourself creating a bunch of related variables and functions and want to track them all together and package them neatly, an object is a good idea. Objects are also very useful when you want to pass a collection of data from one place to another. Both of these things can be achieved without use of constructors or inheritance. If you only need a single instance of an object, then you are probably better off just using an object literal, and you certainly don't need inheritance.</p> + +<h2 id="Alternatives_for_extending_the_prototype_chain">Alternatives for extending the prototype chain</h2> + +<p>In JavaScript, there are several different ways to extend the prototype of an object aside from what we've shown above. To find out more about the other ways, visit our <a href="/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Different_ways_to_create_objects_and_the_resulting_prototype_chain">Inheritance and the prototype chain</a> article.</p> + +<h2 id="Test_your_skills!">Test your skills!</h2> + +<p>You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see <a href="/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript">Test your skills: Object-oriented JavaScript</a>.</p> + +<h2 id="Summary">Summary</h2> + +<p>This article has covered the remainder of the core OOJS theory and syntax that we think you should know now. At this point you should understand JavaScript object and OOP basics, prototypes and prototypal inheritance, how to create classes (constructors) and object instances, add features to classes, and create subclasses that inherit from other classes.</p> + +<p>In the next article we'll have a look at how to work with JavaScript Object Notation (JSON), a common data exchange format written using JavaScript objects.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — A really useful interactive learning site for learning about objects.</li> + <li><a href="https://www.manning.com/books/secrets-of-the-javascript-ninja-second-edition">Secrets of the JavaScript Ninja</a>, Chapter 7 — A good book on advanced JavaScript concepts and techniques, by John Resig, Bear Bibeault, and Josip Maras. Chapter 7 covers aspects of prototypes and inheritance really well; you can probably track down a print or online copy fairly easily.</li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/README.md">You Don't Know JS: this & Object Prototypes</a> — Part of Kyle Simpson's excellent series of JavaScript manuals, Chapter 5 in particular looks at prototypes in much more detail than we do here. We've presented a simplified view in this series of articles aimed at beginners, whereas Kyle goes into great depth and provides a more complex but more accurate picture.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> diff --git a/files/de/learn/javascript/objects/json/index.html b/files/de/learn/javascript/objects/json/index.html new file mode 100644 index 0000000000..7b01bfbf52 --- /dev/null +++ b/files/de/learn/javascript/objects/json/index.html @@ -0,0 +1,345 @@ +--- +title: Arbeiten mit JSON +slug: Learn/JavaScript/Objects/JSON +translation_of: Learn/JavaScript/Objects/JSON +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Die JavaScript Object Notation (JSON) ist ein standardisiertes, textbasiertes Format, um strukturierte Daten auf Basis eines JavaScript Objekts darzustellen. Es wird häufig für die Übertragung von Daten in Webanwendungen verwendet (z.B. das Senden einiger Daten vom Server zum Client, damit sie auf einer Webseite angezeigt werden können oder umgekehrt). Es wird dir sehr häufig über den Weg laufen, daher geben wir dir in diesem Artikel alles mit, damit du JSON mithilfe von JavaScript nutzen kannst, einschließlich des Umwandelns von JSON, damit du auf die enthaltenen Daten zugreifen und JSON erstellen kannst.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Voraussetzungen:</th> + <td>Grundlegende Computerkenntnisse, grundlegendes Verständnis von HTML, CSS und JavaScript (siehe <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> und <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) sowie OOJS Grundkenntnisse (siehe <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> + </tr> + <tr> + <th scope="row">Ziele:</th> + <td>Zu verstehen, wie man mit Daten im JSON-Format arbeitet und eigene JSON-Objekte erstellt.</td> + </tr> + </tbody> +</table> + +<h2 id="Nein_im_ernst_was_ist_JSON">Nein, im ernst, was ist JSON?</h2> + +<p>{{glossary("JSON")}} ist ein textbasierendes Datenformat angelehnt an die JavaScript Object Syntax und popularisiert durch <a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a>. Auch wenn es der JavaScript Object Syntax ähnelt, ist es dennoch Javascript unabhängig. Heutzutage unterstützen zahlreiche Programmierumgebungen JSON, sowohl lesend (parse) als auch schreibend.</p> + +<p>JSON existiert als eine Zeichenkette (String) — das ist nützlich, um Daten über das Netzwerk zu übermitteln. Es muss in ein natives JavaScript Objekt umgewandelt werden, wenn du auf die Daten zugreifen willst. Das ist kein großes Ding — JavaScript stellt ein globales JSON-Objekt zur Verfügung, das Methoden zur Konvertierung zwischen den beiden zur Verfügung stellt.</p> + +<div class="note"> +<p><strong>Note</strong>: Eine Zeichenkette in ein natives Objekt umzuwandeln nennt man <em>parsing</em>, wohingegen die Umwandlung eines nativen Objekts in eine Zeichenkette, um es im Netzwerk zu übermitteln, <em>stringification</em> genannt wird.</p> +</div> + +<p>Ein JSON Objekt kann als einfache Textdatei mit der Endung <code>.json</code> gespeichert werden oder einen {{glossary("MIME type")}} als <code>application/json</code>.</p> + +<h3 id="JSON_Struktur">JSON Struktur</h3> + +<p>Wie bereits erwähnt, ist JSON ein textbasierendes Datenformat angelehnt an die JavaScript Object Syntax. Es können sowohl in JSON als auch in JavaScript Objekten die gleichen Datentypen verwendet werden — Strings, Zahlen, Arrays, Booleans und andere Objekttypen. Das erlaubt es dir, eine Datenhierarchie zu erstellen. Z.B.:</p> + +<pre class="brush: json">{ + "squadName": "Super hero squad", + "homeTown": "Metro City", + "formed": 2016, + "secretBase": "Super tower", + "active": true, + "members": [ + { + "name": "Molecule Man", + "age": 29, + "secretIdentity": "Dan Jukes", + "powers": [ + "Radiation resistance", + "Turning tiny", + "Radiation blast" + ] + }, + { + "name": "Madame Uppercut", + "age": 39, + "secretIdentity": "Jane Wilson", + "powers": [ + "Million tonne punch", + "Damage resistance", + "Superhuman reflexes" + ] + }, + { + "name": "Eternal Flame", + "age": 1000000, + "secretIdentity": "Unknown", + "powers": [ + "Immortality", + "Heat Immunity", + "Inferno", + "Teleportation", + "Interdimensional travel" + ] + } + ] +}</pre> + +<p>Würden wir das Objekt in ein JavaScript Programm laden und die Variable <code>superHeroes</code> auslesen, könnten wir die Objektdaten mittels der gleichen <code>dot/bracket notation</code> abrufen, wie in diesem Artikel behandelt: <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript object basics</a>. Zum Beispiel:</p> + +<pre class="brush: js">superHeroes.homeTown +superHeroes['active']</pre> + +<p>Um Daten in tieferen hierarchischen Ebenen abrufen zu können, müssen die benötigten Eigenschaften und Array-indizes aneinandergereiht werden. Um beispielsweise die dritte <code>superpower</code> des zweiten <code>hero</code> in der <code>members</code> Liste abrufen zu können, würdest du sowas machen:</p> + +<pre class="brush: js">superHeroes['members'][1]['powers'][2]</pre> + +<ol> + <li>Zuerst haben wir den Variablennamen — <code>superHeroes</code>.</li> + <li>Darin wollen wir die <code>members</code> Eigenschaft abrufen, also benutzen wir<code>["members"]</code>.</li> + <li><code>members</code> beinhaltet ein Array mit Objekten. Wir wollen das zweite Objekt innerhalb des Arrays abrufen, also benutzen wir <code>[1]</code>.</li> + <li>Innerhalb des Objekts wollen wir die <code>powers</code> Eigenschaft abrufen, demnach benutzen wir <code>["powers"]</code>.</li> + <li>Die <code>powers</code> Eigenschaft ist ein Array, welches die gewählten <code>superpowers</code> der <code>heroe</code>s hält. Wir wollen die dritte <code>superpower</code>, also <code>[2]</code>.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: Wir haben euch das zuvor erwähnte JSON in einer Variable in unserem <a href="http://mdn.github.io/learning-area/javascript/oojs/json/JSONTest.html">JSONTest.html</a> Beispiel (siehe <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/JSONTest.html">source code</a>) zur Verfügung gestellt. Versuche es hochzuladen und die Daten in der Variable mittels der JavaScript Konsole deines Browser's abzurufen.</p> +</div> + +<h3 id="Arrays_als_JSON">Arrays als JSON</h3> + +<p>Eben haben wir angemerkt, dass JSON Text im Grunde wie ein JavaScript object aussieht, und das ist weitestgehend richtig. "Weitestgehend" da ein Array eben gültiges(valid) JSON darstellt, zum Beispiel:</p> + +<pre class="brush: json">[ + { + "name": "Molecule Man", + "age": 29, + "secretIdentity": "Dan Jukes", + "powers": [ + "Radiation resistance", + "Turning tiny", + "Radiation blast" + ] + }, + { + "name": "Madame Uppercut", + "age": 39, + "secretIdentity": "Jane Wilson", + "powers": [ + "Million tonne punch", + "Damage resistance", + "Superhuman reflexes" + ] + } +]</pre> + +<p>Dieses Arrays ist komplett gültges JSON. Die Array Elemente müssen lediglich beginnend mit des Array's Index - z.B. <code>[0]["powers"][0]</code> - abgerufen werden.</p> + +<h3 id="Anmerkungen"> Anmerkungen</h3> + +<ul> + <li>JSON ist ein reines Datenformat — es beinhaltet nur Eigenschaften, keine Methoden.</li> + <li>JSON benötigt <strong>immer</strong> doppelte Anführungszeichen - also <code>" "</code> - bei Strings und Eigenschaftsnamen. Einfache Anführungszeichen - also <code>' '</code> - sind nicht zulässig (invalid).</li> + <li>Ein einziges deplaziertes Kommata oder ähnliches lässt eine JSON Datei korrupieren und fehlschlagen. Du solltest alle Daten mit denen du arbeitest oder die du verarbeiten möchtest gründlich überprüfen (wobei computer-generiertes JSON bei korrekt funktionierenden JSON generatoren eher nicht fehleranfällig ist). Um dein JSON zu überprüfen, kannst du zum Beispiel eine Anwendung wie <a href="http://jsonlint.com/">JSONLint</a> benutzen.</li> + <li>JSON kann jeden Datentyp der zur Einbindung in JSON geeignet ist annehmen, nicht nur Arrays oder Objekte. So kann zum Beispiel ein einfacher <code>String </code>oder eine <code>number</code> ein gültiges JSON Objekt sein.</li> + <li>Im Gegensatz zu JavaScript Code in dem Objekt Eigenschaften Anführungszeichen nicht zwingend benötigen, dürfen in JSON nur <code>strings </code>in Anführungszeichen als Objekt Eigenschaften genutzt werden. </li> +</ul> + +<h2 id="Aktives_Lernen_Arbeiten_mithilfe_eines_JSON_Beispiels">Aktives Lernen: Arbeiten mithilfe eines JSON Beispiels</h2> + +<p>Lasst uns durch ein Beispiel durcharbeiten um zu veranschaulichen wie wir mit JSON Daten auf einer Webseite arbeiten können.</p> + +<h3 id="Los_Geht's">Los Geht's</h3> + +<p>Anfangs, mache lokale Kopien unserer <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes.html">heroes.html</a> und <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/style.css">style.css</a> Dateien. Letztere enthält ein paar einfache CSS Elemente um unsere Seite ein wenig zu stylen, während die Erste einen einfachen HTML <code>body </code>enthält:</p> + +<pre class="brush: html"><header> +</header> + +<section> +</section></pre> + +<p>Und ein {{HTMLElement("script")}} Element, welches den JavaScript Code halten wird, den wir etwas später erstellen werden. Momentan existieren nur zwei Zeilen, welche auf das {{HTMLElement("header")}} und {{HTMLElement("section")}} Element referenzieren und sie in Variablen speichern:</p> + +<pre class="brush: js">var header = document.querySelector('header'); +var section = document.querySelector('section');</pre> + +<p>Wir haben unsere JSON Daten auf unserem GitHub Account veröffentlicht: <a href="https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json</a>.</p> + +<p>Wir laden es in unsere Seite und benutzen geschickt die DOM Manipulation um es so darzustellen:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13857/json-superheroes.png" style="display: block; margin: 0 auto;"></p> + +<h3 id="JSON_erhalten">JSON erhalten</h3> + +<p>Um JSON zu erhalten, werden wir unsere API, genannt {{domxref("XMLHttpRequest")}} (oft <strong>XHR </strong>genannt), benutzen. Es handelt sich um ein sehr nützliches JavaScript Objekt, das es uns erlaubt, Netzwerkabfragen auszuführen um Ressourcen eines Servers via JavaScript (e.g. Bilder, Text, JSON, sogar HTML snippets) zu erhalten. So können wir kleine Sektionen mit Inhalt aktualisieren ohne die komplette Seite neuzuladen. Das führt zu responsiveren Webseiten und klingt ziemlich spannend. Allerdings fällt es außerhalb des hier behandelten Themas um es ausführlicher zu erklären.</p> + +<ol> + <li>Zuerst werden wir die JSON URL die wir abrufen möchten in einer Variable speichern. Füge Folgendes zum Ende deines JavaScript Codes hinzu: + <pre class="brush: js">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';</pre> + </li> + <li>Um eine Abfrage zu erstellen, müssen wir eine neue Objekt-Abfrage-Instanz des <code>XMLHttpRequest</code> constructors mit dem Keyword <code>new </code>erstellen. Füge Folgenden Code hinzu: + <pre class="brush: js">var request = new XMLHttpRequest();</pre> + </li> + <li>Nun müssen wir eine neue Abfrage mit der <code><a href="/en-US/docs/Web/API/XMLHttpRequest/open">open()</a></code> Methode eröffnen. Füge Folgenden Code hinzu: + <pre class="brush: js">request.open('GET', requestURL);</pre> + + <p>Die Methode braucht mindestens zwei Parameter — wobei es weitere optionale Parameter gibt. Für dieses Beispiel werden wir uns jedoch nur den einfachen, zwingend erforderlichen Parametern widmen :</p> + + <ul> + <li>Die HTTP Methode die für die Netzwerkabfrage erforderlich ist. In diesem Fall reicht <code><a href="/en-US/docs/Web/HTTP/Methods/GET">GET</a> </code>aus, da wir ja nur simple Daten erhalten wollen .</li> + <li>Die Ziel-URL — Die JSON URL die wir zuvor in der <code>requestURL</code> Variable gespeichert haben.</li> + </ul> + </li> + <li>Füge als Nächstes folgende Zeilen hinzu — hier setzen wir den <code><a href="/en-US/docs/Web/API/XMLHttpRequest/responseType">responseType</a></code> auf JSON, sodass XHR weiß, dass der Server JSON zurückgeben und im Hintergrund in ein JavaScript Objekt konvertiert werden soll. Anschließend versenden wir die Abfrage mit der <code><a href="/en-US/docs/Web/API/XMLHttpRequest/send">send()</a></code> Methode: + <pre class="brush: js">request.responseType = 'json'; +request.send();</pre> + </li> + <li>Zu guter Letzt müssen wir auf die Antwort des Servers (response) warten und sie anschließend weiterverarbeiten. Füge folgenden Code hinter deinem bisherigen Code hinzu: + <pre class="brush: js">request.onload = function() { + var superHeroes = request.response; + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + </li> +</ol> + +<p>Hier speichern wir die Response zu unserer Abfrage (verfügbar in der <code><a href="/en-US/docs/Web/API/XMLHttpRequest/response">response</a></code> Eigenschaft) in einer Variable namens: <code>superHeroes</code>; Diese Variable enthält nun das JavaScript Objekt basieren auf dem JSON! Nun geben wir das Objekt an zwei Funktionsaufrufe weiter— der erste wird den <<code>header></code> mit korrekte Daten füllen, während der zweite einen Informationssteckbrief eines jeden Helden im Team erstellt und es in die <code><section></code>einfügt.</p> + +<p>Wir packen den Code in einen Eventhandler der ausgeführt wird, sobald das <code>load </code>event auf das Request Objekt angestoßen wird (siehe <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) — das passiert, da das <code>load </code>Event angestoßen wird sobald die <code>response </code>erfolgreich zurückgegeben wurde. Das garantiert, dass <code>request.response</code> definitiv verfügbar sein wird, wenn wir damit etwas machen wollen.</p> + +<h3 id="Populating_the_header">Populating the header</h3> + +<p>Wir haben also die JSON Daten bekommen und in ein JavaScript Objekt konvertiert. Nun arbeiten wir damit und schreiben zwei Funktionen. Als Erstes, füge folgende Funktion unter deinen bisherigen Code:</p> + +<pre class="brush: js">function populateHeader(jsonObj) { + var myH1 = document.createElement('h1'); + myH1.textContent = jsonObj['squadName']; + header.appendChild(myH1); + + var myPara = document.createElement('p'); + myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed']; + header.appendChild(myPara); +}</pre> + +<p>Wir haben den Parameter <code>jsonObj </code>aufgerufen, um uns daran zu erinnern, dass das JavaScript Objekt seinen Ursprung in JSON hat. Wir erstellen zunächst ein {{HTMLElement("h1")}} element with <code><a href="/en-US/docs/Web/API/Document/createElement">createElement()</a></code>, set its <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code> to equal the <code>squadName</code> property of the object, then append it to the header using <code><a href="/en-US/docs/Web/API/Node/appendChild">appendChild()</a></code>. We then do a very similar operation with a paragraph: create it, set its text content and append it to the header. The only difference is that its text is set to a concatenated string containing both the <code>homeTown</code> and <code>formed</code> properties of the object.</p> + +<h3 id="Creating_the_hero_information_cards">Creating the hero information cards</h3> + +<p>Next, add the following function at the bottom of the code, which creates and displays the superhero cards:</p> + +<pre class="brush: js">function showHeroes(jsonObj) { + var heroes = jsonObj['members']; + + for (var i = 0; i < heroes.length; i++) { + var myArticle = document.createElement('article'); + var myH2 = document.createElement('h2'); + var myPara1 = document.createElement('p'); + var myPara2 = document.createElement('p'); + var myPara3 = document.createElement('p'); + var myList = document.createElement('ul'); + + myH2.textContent = heroes[i].name; + myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity; + myPara2.textContent = 'Age: ' + heroes[i].age; + myPara3.textContent = 'Superpowers:'; + + var superPowers = heroes[i].powers; + for (var j = 0; j < superPowers.length; j++) { + var listItem = document.createElement('li'); + listItem.textContent = superPowers[j]; + myList.appendChild(listItem); + } + + myArticle.appendChild(myH2); + myArticle.appendChild(myPara1); + myArticle.appendChild(myPara2); + myArticle.appendChild(myPara3); + myArticle.appendChild(myList); + + section.appendChild(myArticle); + } +}</pre> + +<p>To start with, we store the <code>members</code> property of the JavaScript object in a new variable. This array contains multiple objects that contain the information for each hero.</p> + +<p>Next, we use a <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">for loop</a> to loop through each object in the array. For each one, we:</p> + +<ol> + <li>Create several new elements: an <code><article></code>, an <code><h2></code>, three <code><p></code>s, and a <code><ul></code>.</li> + <li>Set the <h2> to contain the current hero's <code>name</code>.</li> + <li>Fill the three paragraphs with their <code>secretIdentity</code>, <code>age</code>, and a line saying "Superpowers:" to introduce the information in the list.</li> + <li>Store the <code>powers</code> property in another new variable called <code>superPowers</code> — this contains an array that lists the current hero's superpowers.</li> + <li>Use another <code>for</code> loop to loop through the current hero's superpowers — for each one we create a <code><li></code> element, put the superpower inside it, then put the <code>listItem</code> inside the <code><ul></code> element (<code>myList</code>) using <code>appendChild()</code>.</li> + <li>The very last thing we do is to append the <code><h2></code>, <code><p></code>s, and <code><ul></code> inside the <code><article></code> (<code>myArticle</code>), then append the <code><article></code> inside the <code><section></code>. The order in which things are appended is important, as this is the order they will be displayed inside the HTML.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: If you are having trouble getting the example to work, try referring to our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished.html">heroes-finished.html</a> source code (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished.html">running live</a> also.)</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: If you are having trouble following the dot/bracket notation we are using to access the JavaScript object, it can help to have the <a href="http://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">superheroes.json</a> file open in another tab or your text editor, and refer to it as you look at our JavaScript. You should also refer back to our <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript object basics</a> article for more information on dot and bracket notation.</p> +</div> + +<h2 id="Converting_between_objects_and_text">Converting between objects and text</h2> + +<p>The above example was simple in terms of accessing the JavaScript object, because we set the XHR request to convert the JSON response directly into a JavaScript object using:</p> + +<pre class="brush: js">request.responseType = 'json';</pre> + +<p>But sometimes we aren't so lucky — sometimes we'll receive a raw JSON string, and we'll need to convert it to an object ourselves. And when we want to send a JavaScript object across the network, we'll need to convert it to JSON (a string) before sending. Luckily, these two problems are so common in web development that a built-in <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> object is available in browsers, which contains the following two methods:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">parse()</a></code>: Accepts a JSON string as a parameter, and returns the corresponding JavaScript object.</li> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">stringify()</a></code>: Accepts an object as a parameter, and returns the equivalent JSON string form.</li> +</ul> + +<p>You can see the first one in action in our <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished-json-parse.html">heroes-finished-json-parse.html</a> example (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished-json-parse.html">source code</a>) — this does exactly the same thing as the example we built up earlier, except that we set the XHR to return the raw JSON text, then used <code>parse()</code> to convert it to an actual JavaScript object. The key snippet of code is here:</p> + +<pre class="brush: js">request.open('GET', requestURL); +request.responseType = 'text'; // now we're getting a string! +request.send(); + +request.onload = function() { + var superHeroesText = request.response; // get the string from the response + var superHeroes = JSON.parse(superHeroesText); // convert it to an object + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + +<p>As you might guess, <code>stringify()</code> works the opposite way. Try entering the following lines into your browser's JavaScript console one by one to see it in action:</p> + +<pre class="brush: js">var myJSON = { "name": "Chris", "age": "38" }; +myJSON +var myString = JSON.stringify(myJSON); +myString</pre> + +<p>Here we're creating a JavaScript object, then checking what it contains, then converting it to a JSON string using <code>stringify()</code> — saving the return value in a new variable — then checking it again.</p> + +<h2 id="Summary">Summary</h2> + +<p>In this article, we've given you a simple guide to using JSON in your programs, including how to create and parse JSON, and how to access data locked inside it. In the next article, we'll begin looking at object-oriented JavaScript.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON object reference page</a></li> + <li><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest object reference page</a></li> + <li><a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest">Using XMLHttpRequest</a></li> + <li><a href="/en-US/docs/Web/HTTP/Methods">HTTP request methods</a></li> + <li><a href="http://json.org">Official JSON web site with link to ECMA standard</a></li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</p> + +<p> </p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> + +<p> </p> diff --git a/files/de/learn/javascript/objects/object-oriented_js/index.html b/files/de/learn/javascript/objects/object-oriented_js/index.html new file mode 100644 index 0000000000..b4229a8058 --- /dev/null +++ b/files/de/learn/javascript/objects/object-oriented_js/index.html @@ -0,0 +1,290 @@ +--- +title: Objektorientiertes JavaScript für Beginner +slug: Learn/JavaScript/Objects/Object-oriented_JS +tags: + - Anfänger + - Artikel + - Erstellen + - Erzeugen + - Instanzen + - JavaScript + - Konstruktor + - Lernen + - OOJS + - OOP + - Objekt + - Objektorientiert + - codescripting +translation_of: Learn/JavaScript/Objects/Object-oriented_JS +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Mit den nun bereits erlangten Grundlagen werden wir uns jetzt auf objektorientiertes JavaScript (OOJS) konzentrieren - dieser Artikel vermittelt Grundlagen der Theorie der objektorientierten Programmierung (OOP). Anschließend wird näher betrachtet, wie JavaScript Objektklassen über Konstruktor-Funktionen emuliert und wie Objekt-Instanzen erzeugt werden.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Voraussetzungen:</th> + <td> + <p>Grundlegende Computerkenntnisse, ein grundlegendes Verständnis von HTML und CSS, Vertrautheit mit den Grundlagen von JavaScript (siehe <a href="/de/docs/Learn/JavaScript/First_steps">erste Schritte</a> und <a href="/de/docs/Learn/JavaScript/Bausteine">Bausteine</a>) und OOJS-Grundlagen (siehe <a href="/de/docs/Learn/JavaScript/Objects/Basics">Einführung in Objekte</a>).</p> + </td> + </tr> + <tr> + <th scope="row">Ziel:</th> + <td>Die grundlegende Theorie hinter der objektorientierten Programmierung und wie diese in JavaScript umgesetzt ist ("alles ist ein Objekt") zu verstehen, und wie man Konstruktoren und Objektinstanzen erstellt.</td> + </tr> + </tbody> +</table> + +<h2 id="Objektorientierte_Programmierung_-_Grundlagen">Objektorientierte Programmierung - Grundlagen</h2> + +<p>Um zu beginnen möchten wir Ihnen eine vereinfachende und umfangreiche Übersicht darüber geben, was objektorientierte Programmierung (OOP) ist. Wir sagen vereinfachend, weil OOP schnell sehr kompliziert werden kann und an dieser Stelle eine vollständige Einführung sehr wahrscheinlich mehr verwirren als helfen würde. Die Grundidee von OOP ist, dass wir Objekte verwenden, um Dinge aus der realen Welt zu modellieren, die wir in unseren Programmen abbilden wollen und/oder eine einfache Möglichkeit bieten möchten, auf Funktionen zuzugreifen, die sonst nur schwer oder gar nicht genutzt werden könnten.</p> + +<p>Objekte können in Beziehung stehende Daten und Code enthalten, die Informationen über die Sache darstellen, die Sie modellieren möchten, sowie Funktionalitäten bzw. Verhalten, die Sie erhalten bzw. bereitstellen möchten. Objektdaten (und oft auch Funktionen) können geordnet (das Fachwort dafür lautet "gekapselt") innerhalb eines Objektpakets gespeichert werden (dem ein bestimmter Name gegeben werden kann, auf den man sich beziehen kann, der manchmal auch "Namensraum" genannt wird), wodurch es leicht strukturiert und zugänglich wird. Objekte werden auch häufig als Datenspeicher verwendet, die einfach über das Netzwerk gesendet werden können.</p> + +<h3 id="Definieren_einer_Objektvorlage">Definieren einer Objektvorlage</h3> + +<p>Betrachten wir ein einfaches Programm, das Informationen über die Schüler und Lehrer einer Schule anzeigt. Hier betrachten wir die OOP-Theorie im Allgemeinen, nicht im Zusammenhang mit einer bestimmten Programmiersprache.</p> + +<p>Um damit zu beginnen, könnten wir zu unserem <code>person</code>-Objekt aus dem vorhergehenden Kapitel zurückkehren, in dem wir Informationen und Funktionalitäten einer Person definiert hatten. Es gibt viele Dinge, die man über eine Person wissen kann (ihre Adresse, Größe, Schuhgröße, DNA-Profil, Ausweisnummer, signifikante Persönlichkeitsmerkmale ...), aber in diesem Fall sind wir nur daran interessiert, ihren Namen, ihr Alter, ihr Geschlecht und ihre Interessen zu betrachten. Und wir wollen auch in der Lage sein, eine kurze Erläuterung über sie auf der Grundlage dieser Daten zu schreiben und sie dazu zu bringen, "Hallo" zu sagen. Dies wird als "Abstraktion" bezeichnet - ein einfaches Modell einer komplexeren Sache wird erstellt, das die wichtigsten Aspekte in einer Weise darstellt, die für die Zwecke unseres Programms leicht zu bearbeiten sind.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13889/person-diagram.png" style="display: block; height: 219px; margin: 0px auto; width: 610px;"></p> + +<h3 id="Erstellen_von_realen_Objekten">Erstellen von realen Objekten</h3> + +<p>Von unserer Klasse können wir Objektinstanzen erstellen - Objekte die Informationen und Funktionalitäten enthalten, die in der Klasse definiert worden. Von unserer Klasse <code>person</code> können wir nun einige tatsächliche Personen erzeugen:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15163/MDN-Graphics-instantiation-2-fixed.png" style="display: block; height: 702px; margin: 0px auto; width: 695px;"></p> + +<p>Wenn eine Objektinstanz aus einer Klasse erzeugt wurde, wird die Konstruktorfunktion der Klasse ausgeführt, um die Objektinstanz zu erzeugen. Dieser Vorgang der Erzeugung einer Objektinstanz aus einer Klasse wird als Instanziierung bezeichnet - die Objektinstanz wird von der Klasse aus instanziiert.</p> + +<h3 id="Spezialisierte_Klassen">Spezialisierte Klassen</h3> + +<p>In diesem Fall wollen wir keine allgemeinen Leute - wir wollen Lehrer und Schüler, die beide spezifischere Typen von Menschen sind. In OOP können wir neue Klassen erstellen, die auf anderen Klassen basieren - diese neuen Unterklassen können die Daten- und Funktionalitäten ihrer Elternklasse erben, so dass Sie die Funktionalitäten, die allen Objekttypen gemeinsam ist, wiederverwenden können, anstatt sie duplizieren zu müssen. Da wo sich Funktionalitäten zwischen den Klassen unterscheiden soll, können bei Bedarf spezialisierte Features direkt in den betroffenen Klassen entsprechend definieren.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13881/MDN-Graphics-inherited-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p>Das ist wirklich sehr nützlich - Lehrer und Schüler haben viele gemeinsame Merkmale wie Name, Geschlecht und Alter, so dass es praktisch ist, diese Merkmale nur einmal zu definieren. Sie können dasselbe Merkmal auch separat in verschiedenen Klassen definieren, da jede Definition dieses Merkmals in einem anderen Namensraum liegt. Die Begrüßung eines Schülers könnte z.B. die Form "Yo, ich bin <code>firstName</code>" haben (z.B. Yo, ich bin Sam), während ein Lehrer etwas formelleres verwenden könnte, wie z.B. "Hallo, mein Name ist <code>prefix</code> <code>lastName</code> und ich unterrichte <code>Subject</code>". (z.B. Hallo, ich heiße Mr. Griffiths und unterrichte Chemie).</p> + +<div class="note"> +<p><strong>Hinweis:</strong> Das Fachwort für die Fähigkeit, mehrere Objekttypen mit der gleichen Funktionalität zu implementieren, nennt man Polymorphismus. Nur für den Fall, dass Sie sich das fragen.</p> +</div> + +<p>Sie können nun Objektinstanzen aus Ihren Unterklassen erzeugen. Beispiel:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13885/MDN-Graphics-instantiation-teacher-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p>Im weiteren Verlauf dieses Kapitels werden wir uns damit beschäftigen, wie die OOP-Theorie in JavaScript in die Praxis umgesetzt werden kann.</p> + +<h2 id="Konstruktoren_und_Objektinstanzen">Konstruktoren und Objektinstanzen</h2> + +<p>JavaScript verwendet spezielle Funktionen, die "Konstruktor-Funktionen" genannt werden, um Objekte und deren Eigenschaften zu definieren und zu initialisieren. Sie sind nützlich, weil Sie oft auf Situationen stoßen werden, in denen Sie nicht wissen, wie viele Objekte Sie erstellen werden müssen. Konstruktoren bieten die Möglichkeit, so viele Objekte wie nötig auf einfache und effektive Weise zu erstellen, indem sie alle erforderlichen Daten und Funktionen an diese Objekte anhängen.</p> + +<p>Lassen Sie uns nun das Erstellen von Klassen über Konstruktoren und das Erstellen von Objektinstanzen aus ihnen heraus speziell in JavaScript untersuchen. Zuerst möchten wir Sie bitten, eine neue lokale Kopie der oojs.html-Datei zu erstellen, die wir im vorhergehenden Kapitel bereits benutzt haben.</p> + +<h3 id="Ein_einfaches_Beispiel">Ein einfaches Beispiel</h3> + +<ol> + <li>Fangen wir damit an, wie man eine Person mit einer normalen Funktion definieren könnte. Fügen Sie diese Funktion innerhalb des Skript-Elements der oojs.html hinzu: + <pre class="brush: js">function createNewPerson(name) { + var obj = {}; + obj.name = name; + obj.greeting = function() { + alert('Hi! I\'m ' + obj.name + '.'); + }; + return obj; +}</pre> + </li> + <li>Sie können nun eine neue Person erstellen, indem Sie diese Funktion aufrufen - bitte geben Sie die folgenden Zeilen in der JavaScript-Konsole Ihres Browsers ein: + <pre class="brush: js">var salva = createNewPerson('Salva'); +salva.name; +salva.greeting();</pre> + Das funktioniert zwar ganz gut, aber es ist ein bisschen umständlich. Wenn wir wissen, dass wir ein Objekt erstellen wollen, warum müssen wir dann explizit ein neues leeres Objekt erstellen und es zurückgeben? Glücklicherweise bietet uns JavaScript eine praktische Vereinfachung in Form von Konstruktorfunktionen - nutzen wir jetzt eine!</li> + <li>Ersetzen Sie die vorher implementierte Funktion durch folgende: + <pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + </li> +</ol> + +<p>Die Konstruktorfunktion ist die JavaScript-Version einer Klasse. Sie werden feststellen, dass sie alle Eigenschaften hat, die man in einer Funktion erwartet, obwohl sie weder etwas zurückgibt oder explizit ein Objekt erzeugt - sie definiert im Grunde nur Eigenschaften und Methoden. Sie werden sehen, dass dieses Schlüsselwort auch hier verwendet wird - es besagt im Grunde, dass immer dann, wenn eine dieser Objektinstanzen erzeugt wird, die Eigenschaft <code>name</code> des Objekts gleich dem Namenswert ist, der an den Konstruktoraufruf übergeben wird, und die Methode <code>greeting()</code> wird ebenfalls den Namenswert verwenden, der an den Konstruktoraufruf übergeben wird.</p> + +<div class="note"> +<p><strong>Hinweis:</strong> Der Name einer Konstruktorfunktion beginnt normalerweise mit einem Großbuchstaben - diese Konvention wird verwendet, um Konstruktorfunktionen im Code leichter erkennbar zu machen.</p> +</div> + +<p>Wie rufen wir also einen Konstruktor auf, um einige Objekte zu erstellen?</p> + +<ol> + <li>Fügen Sie die folgenden Zeilen unterhalb Ihres vorherigen Codezusatzes ein: + <pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + </li> + <li>Speichern Sie Ihren Code, laden Sie ihn im Browser neu und geben Sie die folgenden Zeilen in Ihre JS-Konsole ein: + <pre class="brush: js">person1.name +person1.greeting() +person2.name +person2.greeting()</pre> + </li> +</ol> + +<p>Cool! Sie werden nun sehen, dass wir zwei neue Objekte auf der Seite haben, die jeweils unter einem anderen Namespace gespeichert sind - wenn Sie auf ihre Eigenschaften und Methoden zugreifen, müssen Sie Aufrufe mit <code>person1</code> oder <code>person2</code> starten; die darin enthaltene Funktionalität ist sauber verpackt, damit sie nicht mit anderen Funktionen kollidiert. Sie haben jedoch die gleiche Namenseigenschaft und die gleiche Methode <code>greeting()</code> zur Verfügung. Beachten Sie, dass Sie Ihren eigenen Namenswert verwenden, der Ihnen bei der Erstellung zugewiesen wurde. Das ist ein Grund, warum es sehr wichtig ist, diesen zu verwenden, so dass Sie Ihre eigenen Werte verwenden werden, und nicht irgendeinen anderen Wert.</p> + +<p>Sehen wir uns die Konstruktoraufrufe noch einmal genauer an:</p> + +<pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + +<p>In jedem Fall wird das neue Schlüsselwort verwendet, um dem Browser mitzuteilen, dass wir eine neue Objektinstanz erstellen wollen, gefolgt vom Funktionsnamen mit den erforderlichen Parametern in Klammern. Das Ergebnis wird in einer Variablen gespeichert - sehr ähnlich wie bei dem Aufruf einer Standardfunktion. Jede Instanz wird entsprechend dieser Definition erzeugt:</p> + +<pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + +<p>Nach dem Anlegen der neuen Objekte enthalten die Variablen <code>person1</code> und <code>person2</code> die folgenden Objekte:</p> + +<pre class="brush: js">{ + name: 'Bob', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +{ + name: 'Sarah', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p>Beachten Sie, dass wir beim Aufruf unserer Konstruktor-Funktion jedes Mal <code>greeting()</code> definieren, was nicht ideal ist. Um dies zu vermeiden, können wir stattdessen Funktionen auf dem Prototypen definieren, die wir uns später genauer ansehen werden.</p> + +<h3 id="Erstellen_unseres_finalen_Konstruktors">Erstellen unseres finalen Konstruktors</h3> + +<p>Das Beispiel, das wir oben betrachtet haben, war nur ein einfaches Beispiel, um den Einstieg zu erleichtern. Lassen Sie uns nun weitermachen und unsere finale Konstruktor-Funktion <code>Person()</code> erstellen.</p> + +<ol> + <li>Entfernen Sie den bisher eingefügten Code und fügen Sie nachfolgenden Konstruktor als Ersatz hinzu - dies ist im Prinzip genau dasselbe, wie das einfache Beispiel, nur etwas komplexer: + <pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + first : first, + last : last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.bio = function() { + alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); + }; + this.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); + }; +}</pre> + </li> + <li>Fügen Sie nun unter dem Code von oben folgende Zeile ein, um eine Objektinstanz zu erzeugen: + <pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + </li> +</ol> + +<p>Sie werden nun sehen, dass Sie auf die Eigenschaften und Methoden zugreifen können, genau wie wir es zuvor getan haben - probieren Sie das in Ihrer JS-Konsole aus:</p> + +<pre class="brush: js">person1['age'] +person1.interests[1] +person1.bio() +// etc.</pre> + +<div class="note"> +<p><strong>Hinweis:</strong> Wenn Sie Probleme haben, dies zum Laufen zu bringen, vergleichen Sie Ihren Code mit unserer Version - siehe <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">hier</a> können Sie auch sehen, wie es live läuft).</p> +</div> + +<h3 id="Weitere_Übungen">Weitere Übungen</h3> + +<p>Versuchen Sie zunächst, ein paar weitere eigene Objekte hinzuzufügen, und versuchen Sie, die Eigenschaften bzw. Funktionen der daraus erzeugten Objektinstanzen zu nutzen bzw. zu verändern.</p> + +<p>Außerdem gibt es einige Probleme mit unserer <code>bio()</code>-Methode - die Ausgabe enthält immer das Pronomen "He", egal ob Ihre <code>Person</code> weiblich ist oder einem anderen Geschlecht angehört. Und die <code>bio()</code>-Methode wird nur zwei Interessen enthalten, auch wenn mehr im Interessen-Array aufgelistet sind. Finden Sie heraus, wie man das in der Klassendefinition (Konstruktor) beheben kann? Sie können jeden beliebigen Code in einen Konstruktor einfügen (Sie werden wahrscheinlich ein paar Bedingungen und eine Schleife benötigen). Überlegen Sie sich, wie die Sätze je nach Geschlecht und je nachdem, ob die Anzahl der aufgelisteten Interessen 1, 2 oder mehr als 2 beträgt, unterschiedlich strukturiert werden sollten.</p> + +<div class="note"> +<p><strong>Hinweis:</strong> Wenn Sie nicht weiterkommen, haben wir eine Antwort bzw. Lösung in unserem <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">GitHub-Repo</a> bereitgestellt (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">Sehen Sie es sich hier an</a>) - versuchen Sie bitte aber erst einmal, die Lösung selbst zu schreiben!</p> +</div> + +<h2 id="Andere_Möglichkeiten_Objektinstanzen_zu_erzeugen">Andere Möglichkeiten, Objektinstanzen zu erzeugen</h2> + +<p>Bisher haben wir zwei verschiedene Wege gesehen, um eine Objektinstanz zu erzeugen - die Deklaration eines Objektes als Literal und die Verwendung einer Konstruktorfunktion (siehe oben).</p> + +<p>Diese machen Sinn, aber es gibt auch andere Wege - wir möchten Sie mit diesen vertraut machen, falls Sie auf Ihren Reisen im Web auf sie stoßen sollten.</p> + +<h3 id="Der_Object-Konstruktor">Der Object()-Konstruktor</h3> + +<p>Zuerst können Sie den <code>Object()</code> Konstruktor verwenden, um ein neues Objekt zu erstellen. Ja, sogar generische Objekte haben einen Konstruktor, der ein leeres Objekt erzeugt.</p> + +<ol> + <li>Geben Sie dies in die JavaScript-Konsole Ihres Browsers ein: + <pre class="brush: js">var person1 = new Object();</pre> + </li> + <li>Diese speichert ein leeres Objekt in der Variable <code>person1</code>. Sie können dann diesem Objekt Eigenschaften und Methoden mit Punkt- oder Klammer-Notation hinzufügen, wie gewünscht. Versuchen Sie diese Beispiele in Ihrer Konsole: + <pre class="brush: js">person1.name = 'Chris'; +person1['age'] = 38; +person1.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); +};</pre> + </li> + <li>Sie können auch ein Objektliteral als Parameter an den <code>Object()</code> Konstruktor übergeben, um es mit Eigenschaften/Methoden vorzufüllen. Versuchen Sie folgendes in Ihrer JS-Konsole: + <pre class="brush: js">var person1 = new Object({ + name: 'Chris', + age: 38, + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +});</pre> + </li> +</ol> + +<h3 id="Verwendung_der_Methode_create">Verwendung der Methode create()</h3> + +<p>Konstruktoren können Ihnen helfen, Ihren Code zu ordnen - Sie können Konstruktoren an einer Stelle erstellen und dann bei Bedarf Instanzen davon erstellen - und es ist immer nachvollziehbar, woher sie kommen.</p> + +<p>Einige Leute ziehen es jedoch vor, Objektinstanzen zu erstellen, ohne vorher Konstruktoren zu erstellen, insbesondere wenn sie nur wenige Instanzen eines Objekts erstellen müssen. JavaScript hat eine eingebaute Methode namens <code>create()</code>, die es Ihnen einfach ermöglicht, dies zu tun. Mit ihr können Sie ein neues Objekt auf Basis eines beliebigen vorhandenen Objekts erstellen.</p> + +<ol> + <li>Wenn Ihre fertige Übung aus den vorherigen Abschnitten im Browser geladen ist, versuchen Sie folgendes in Ihrer JavaScript-Konsole: + <pre class="brush: js">var person2 = Object.create(person1);</pre> + </li> + <li>Nun geben Sie bitte folgendes in die JavaScript-Konsole ein: + <pre class="brush: js">person2.name +person2.greeting()</pre> + </li> +</ol> + +<p>Sie werden sehen, dass <code>person2</code> auf der Basis von <code>person1</code> erstellt wurde - es hat die gleichen Eigenschaften und die gleiche Methode, die ihm zur Verfügung stehen.</p> + +<p>Eine Einschränkung von <code>create()</code> ist, dass der IE8 es nicht unterstützt. Daher können Konstruktoren effektiver sein, wenn Sie ältere Browser unterstützen wollen.</p> + +<p>Wir werden die Auswirkungen von <code>create()</code> später noch genauer untersuchen.</p> + +<h2 id="Zusammenfassung">Zusammenfassung</h2> + +<p>Dieser Artikel hat eine vereinfachte Sicht der objektorientierten Theorie geliefert - das ist noch lange nicht die ganze Geschichte, aber er gibt Ihnen eine Vorstellung davon, womit wir es hier zu tun haben. Darüber hinaus haben wir damit begonnen, verschiedene Möglichkeiten der Erzeugung von Objektinstanzen zu betrachten.</p> + +<p>Im nächsten Artikel werden wir uns mit JavaScript-Objekt-Prototypen beschäftigen.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_diesem_Modul">In diesem Modul</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Objekt Grundlagen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Objektorientiertes JavaScript für Anfänger</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Objekt Prototypen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Vererbung in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Mit JSON Daten arbeiten</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Objekterstellungsübungen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Funktionalität zu unserer Hüpfball Demo hinzufügen</a></li> +</ul> diff --git a/files/de/learn/javascript/objects/object_prototypes/index.html b/files/de/learn/javascript/objects/object_prototypes/index.html new file mode 100644 index 0000000000..010c5986e9 --- /dev/null +++ b/files/de/learn/javascript/objects/object_prototypes/index.html @@ -0,0 +1,288 @@ +--- +title: Object prototypes +slug: Learn/JavaScript/Objects/Object_prototypes +tags: + - Anfänger + - Beitrag + - 'I10n:priority' + - JavaScript + - Konstruktor + - Lernen + - OOJS + - OOP + - Objekt + - Prototypen + - Prototypketten + - codescripting + - create() +translation_of: Learn/JavaScript/Objects/Object_prototypes +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Prototypen dienen als Mechanismus, durch den JavaScript-Objekte Eigenschaften voneinander erben. In diesem Artikel erklären wir, wie Prototypketten funktionieren und betrachten, wie die Prototypeneigenschaft verwendet werden kann, um Methoden zu bestehenden Konstruktoren hinzuzufügen.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Voraussetzungen:</th> + <td> + <p>Verständnis der Funktionen in JavaScript, sowie Vertrautheit mit den Grundlagen von JavaScript (siehe <a href="https://wiki.developer.mozilla.org/de/docs/Learn/JavaScript/First_steps">erste Schritte</a> und <a href="https://wiki.developer.mozilla.org/de/docs/Learn/JavaScript/Bausteine">Bausteine</a>) und OOJS-Grundlagen (siehe <a href="https://wiki.developer.mozilla.org/de/docs/Learn/JavaScript/Objects/Basics">Einführung in Objekte</a>).</p> + </td> + </tr> + <tr> + <th scope="row">Ziel:</th> + <td>JavaScript-Objekt-Prototypen zu verstehen, wie Prototypenketten funktionieren und wie man neue Methoden auf die Prototyp-Eigenschaft hinzufügt.</td> + </tr> + </tbody> +</table> + +<h2 id="Eine_Prototyp-basierte_Sprache">Eine Prototyp-basierte Sprache?</h2> + +<p>JavaScript wird oft als eine <strong>prototypische bzw. Prototyp-basierte Sprache</strong> beschrieben - um Vererbung zu ermöglichen, können Objekte dazu ein <strong>Prototyp-Objekt </strong>haben, das als Vorlageobjekt fungiert, von dem es Methoden und Eigenschaften erbt. Das Prototyp-Objekt eines Objekts kann auch ein Prototyp-Objekt haben, von dem es Methoden und Eigenschaften erbt und so weiter. Dies wird oft als eine <strong>Prototypenkette</strong> bezeichnet und erklärt, warum verschiedene Objekte Eigenschaften und Methoden haben, die auf anderen Objekten definiert sind, die ihnen dadurch zur Verfügung stehen.</p> + +<p>Genau gesagt basieren die Eigenschaften und Methoden auf den Prototyp-Eigenschaften der Konstruktorfunktionen der Objekte, nicht auf den Objektinstanzen selbst.</p> + +<p>In JavaScript wird eine Verbindung zwischen der Objektinstanz und ihrem Prototyp hergestellt (seine <code>__proto__</code>-Eigenschaft, die von der Prototyp-Eigenschaft des Konstruktor abgeleitet ist). Die Eigenschaften und Methoden stammen aus der Kette der Prototypen (aufwärts der Prototypenkette folgend).</p> + +<div class="note"> +<p><strong>Hinweis</strong>: Es ist wichtig zu wissen, dass es einen Unterschied gibt zwischen dem Prototypen eines Objekts (das über <code>Object.getPrototypeOf(obj)</code> oder über die veraltete <code>__proto__</code>-Eigenschaft zur Verfügung gestellt wird) und der Prototyp-Eigenschaft von Konstruktorfunktionen. Erstere ist die Eigenschaft auf jeder Instanz, letztere ist die Eigenschaft auf dem Konstruktor. Das heißt, <code>Object.getPrototypeOf(new Foobar())</code> bezieht sich auf dasselbe Objekt wie <code>Foobar.prototype</code>.</p> +</div> + +<p>Schauen wir uns ein Beispiel an, um dies etwas deutlicher zu machen.</p> + +<h2 id="Verstehen_von_Prototyp-Objekten">Verstehen von Prototyp-Objekten</h2> + +<p>An dieser Stelle gehen wir zu dem Beispiel zurück, an dem wir unsere Konstruktor-Funktion <code>Person()</code> fertig gestellt haben - bitte laden Sie das Beispiel in Ihrem Browser. Sie können dazu gerne auch unsere Beispieldatei <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> nutzen (<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">hier finden Sie den Quellcode</a>), falls Ihnen der Quellcode aus dem vorangegangenen Artikel nicht mehr zur Verfügung steht.</p> + +<p>In diesem Beispiel haben wir eine Konstruktorfunktion wie nachfolgend gezeigt definiert:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // property and method definitions + this.name = { + 'first': first, + 'last' : last + }; + this.age = age; + this.gender = gender; + //...see link in summary above for full definition +}</pre> + +<p>Wir haben dann davon eine Objektinstanz erzeugt, die wie folgt aussieht:</p> + +<pre class="brush: js">let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + +<p>Wenn Sie in Ihre JavaScript-Konsole <code>person1.</code> eingeben, sollten Sie sehen können, das der Browser versucht, die Ausgabe der in dem Objekt verfügbaren Eigenschaften automatisch zu vervollständigen.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13853/object-available-members.png" style="display: block; margin: 0 auto;"></p> + +<p>In dieser Liste können Sie die Eigenschaften sehen, die in der Konstruktor-Funktion <code>person()</code> definiert sind - <code>name</code>, <code>age</code>, <code>gender</code>, <code>interests</code>, <code>bio</code> und <code>greeting</code>. Sie werden jedoch auch einige andere Eigenschaften sehen können - <code>toString</code>, <code>valueOf</code> etc. - diese sind im Prototyp-Objekt der Konstruktor-Funktion <code>person()</code> definiert.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13891/MDN-Graphics-person-person-object-2.png" style="display: block; height: 150px; margin: 0px auto; width: 700px;"></p> + +<p>Was passiert eigentlich, wenn man eine Methode auf <code>person1</code> ausführt, welche aktuell nur im Objekt definiert ist? Zum Beispiel:</p> + +<pre class="brush: js">person1.valueOf()</pre> + +<p>Die Methode <code>Object.valueOf()</code> wird von <code>person1</code> geerbt, weil deren Konstruktor-Funktion <code>person()</code> ist und der Prototyp von <code>person()</code> gleich <code>Object()</code> ist. <code>valueOf()</code> gibt den Wert des Objekts zurück, dass die Methode aufruft - probieren Sie es aus und sehen selber! Was in diesem Fall passiert, sieht wie folgt aus:</p> + +<ul> + <li>Der Browser prüft zunächst, ob für das <code>person1</code>-Objekt eine <code>valueOf()</code>-Methode verfügbar ist, wie sie in seinem Konstruktor <code>Person()</code> definiert ist.</li> + <li>Wenn das nicht der Fall ist, prüft der Browser im Prototyp-Objekt des Konstruktors von <code>Person()</code>, nämlich <code>Object()</code>, ob in diesem eine Methode <code>valueOf()</code> verfügbar ist. Ist dem so, wird die Methode aufgerufen und alles läuft!</li> +</ul> + +<div class="note"> +<p><strong>Hinweis</strong>: Wir möchten nochmals darauf hinweisen, dass die Methoden und Eigenschaften in der Prototypenkette nicht von einem Objekt auf ein anderes kopiert werden, sondern dass der Zugriff auf sie erfolgt, indem man in der Kette wie oben beschrieben nach oben geht.</p> +</div> + +<div class="note"> +<p><strong>Hinweis</strong>: Es gibt keine offizielle Möglichkeit, direkt auf das Prototyp-Objekt eines Objekts zuzugreifen - die "Links" zwischen den Elementen in der Kette sind in einer internen Eigenschaft definiert, die in der Spezifikation für die JavaScript-Sprache als [[prototype]] bezeichnet wird (siehe {{glossary("ECMAScript")}}). Die meisten modernen Browser verfügen jedoch über eine Eigenschaft namens <code>__proto__</code> (mit 2 Unterstrichen auf jeder Seite), die das Prototyp-Objekt des Konstruktors des betroffenen Objekts enthält. Geben Sie zum Beispiel <code>person1.__proto__</code> und <code>person1.__proto__.__proto__</code> in der JavaScript-Konsole ein, um zu sehen, wie die Kette im Code aussieht!</p> + +<p>Seit ECMAScript 2015 können Sie auf das Prototyp-Objekt eines Objekts indirekt über <code>Object.getPrototypeOf(obj)</code> zugreifen.</p> +</div> + +<h2 id="Die_Prototyp-Eigenschaft_Wo_vererbte_Mitglieder_definiert_sind">Die Prototyp-Eigenschaft: Wo vererbte Mitglieder definiert sind</h2> + +<p>Wo sind also die vererbten Eigenschaften und Methoden definiert? Wenn Sie sich die <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object">Referenzseite des Konstruktors object</a> ansehen, sehen Sie auf der linken Seite eine große Anzahl von Eigenschaften und Methoden aufgelistet - viel mehr als die Anzahl der geerbten Eigenschaften, die wir auf dem <code>person1</code>-Objekt gesehen haben. Einige werden vererbt, andere nicht - warum ist das so?</p> + +<p>Wie oben erwähnt sind die geerbten diejenigen, die auf der Prototyp-Eigenschaft (man könnte es einen Unter-Namensraum nennen) definiert sind - damit sind die Eigenschaften gemeint, die mit <code>Object.prototype</code>. beginnen und nicht die, die nur mit Object beginnen. Der Wert der Prototyp-Eigenschaft ist ein Objekt, das im Grunde ein Bereich zum Speichern von Eigenschaften und Methoden ist, die wir an Objekte weiter unten in der Prototyp-Kette vererben wollen.</p> + +<p>Somit stehen <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/toString">Object.prototype.toString()</a>, <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a> usw. für alle Objekttypen zur Verfügung, die von <code>Object.prototype</code> erben, einschließlich neuer Objektinstanzen, die vom <code>Person()</code>-Konstruktor erstellt werden.</p> + +<p><a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a>, <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a> und andere Eigenschaften, die nicht innerhalb des Prototyp-Bereichs definiert sind, werden nicht von Objektinstanzen oder Objekttypen geerbt, die von <code>Object.prototype</code> erben. Sie sind Methoden/Eigenschaften, die nur auf dem <code>Object()</code>-Konstruktor selbst verfügbar sind.</p> + +<div class="note"> +<p><strong>Hinweis</strong>: Das mag ein wenig befremdlich wirken - wie können Sie eine Methode in einem Konstruktor definieren, wenn er selber eine Funktion ist? Eine Funktion ist ebenfalls eine Art Objekt - siehe auch auf der <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function">Referenzseite des function()-Konstruktors</a>, damit Sie es besser nachvollziehen können.</p> +</div> + +<ol> + <li>Sie können die vorhandenen Prototyp-Eigenschaften selbst überprüfen - gehen Sie zurück zu unserem vorherigen Beispiel und geben Sie folgendes in die JavaScript-Konsole ein: + <pre class="brush: js">Person.prototype</pre> + </li> + <li>Die Ausgabe wird Ihnen nicht sehr viel zeigen, da wir nichts im Prototyp unseres <code>Custom</code>-Konstruktors definiert haben! Standardmäßig startet der Prototyp eines Konstruktors immer leer. Versuchen Sie jetzt Folgendes: + <pre class="brush: js">Object.prototype</pre> + </li> +</ol> + +<p>Sie werden eine große Anzahl von Methoden sehen, die in den Prototyp-Eigenschaften des Objekts (<code>Object</code>) definiert sind, die dann auf Objekten verfügbar sind, die von diesem Objekt (<code>Object)</code> erben, wie bereits gezeigt.</p> + +<p>Sie werden weitere Beispiele für die Vererbung von Prototypenketten sehen, die in JavaScript verfügbar sind - versuchen Sie zum Beispiel, nach den Methoden und Eigenschaften zu suchen, die auf dem Prototyp der globalen Objekte <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/String">String</a>, <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a>, <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a> und <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a> definiert sind. Diese haben alle eine Anzahl von Elementen, die auf ihrem Prototyp definiert sind, wie z.B. bei der Erstellung einer Zeichenfolge:</p> + +<pre class="brush: js">let myString = 'This is my string.';</pre> + +<p>myString hat per se eine Reihe nützlicher Methoden zur Verfügung, wie <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/String/split">split()</a>, <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf()</a>, <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> usw.</p> + +<div class="note"> +<p><strong>Hinweis</strong>: Es lohnt sich unseren <a href="/de/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">ausführlicheren Leitfaden zur Verwendung von Prototypen in JavaScript</a> zu lesen, sobald Sie diesen Abschnitt verinnerlicht haben und mehr wissen möchten. Dieser Abschnitt ist absichtlich stark vereinfacht, um diese Konzepte bei der ersten Begegnung für Sie etwas leichter verständlich zu machen.</p> +</div> + +<div class="warning"> +<p><strong>Wichtig:</strong> Die Prototyp-Eigenschaft ist einer der Teile von JavaScript, die stark verwirrend benannt worden sind - man könnte meinen, dass <code>this</code> auf das Prototyp-Objekt des aktuellen Objekts zeigt, aber das tut sie nicht. <code>prototype</code> ist ein internes Objekt, auf das mit <code>__proto__</code> zugegriffen werden kann, erinnern Sie sich?</p> +</div> + +<h2 id="Zurück_zu_create">Zurück zu create()</h2> + +<p>Etwas früher im Beitrag haben wir gezeigt, wie die Methode <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a> verwendet werden kann, um eine neue Objektinstanz zu erzeugen.</p> + +<ol> + <li>Geben Sie folgendes in der JavaScript-Konsole Ihres vorherigen Beispiels ein: + <pre class="brush: js">let person2 = Object.create(person1);</pre> + </li> + <li>Was <code>create()</code> tatsächlich tut, ist lediglich ein neues Objekt aus einem spezifizierten Prototyp-Objekt zu erstellen. Hier wird <code>person2</code> erstellt indem <code>person1</code> als Prototyp Objekt verwendet wird. Man kann das überprüfen indem man das folgende in der Konsole eingibt: + <pre class="brush: js">person2.__proto__</pre> + </li> +</ol> + +<p>Dies wird das <code>person1</code>-Objekt zurückgeben.</p> + +<h2 id="Die_Konstruktor-Eigenschaft">Die Konstruktor-Eigenschaft</h2> + +<p>Jede Konstruktorfunktion hat eine Prototyp-Eigenschaft, deren Wert ein Objekt ist, das eine <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a>-Eigenschaft enthält. Diese Konstruktoreigenschaft zeigt auf die ursprüngliche Konstruktorfunktion. Wie Sie im nächsten Abschnitt sehen werden, werden Eigenschaften, die auf der <code>Person.prototype</code>-Eigenschaft (oder im Allgemeinen auf der Prototyp-Eigenschaft einer Konstruktorfunktion, die ein Objekt ist, wie im obigen Abschnitt erwähnt) definiert sind, für alle Instanzobjekte verfügbar, die mit dem <code>Person()</code>-Konstruktor erstellt werden. Daher ist die Konstruktor-Eigenschaft auch für die beiden Objekte <code>Person1</code> und <code>Person2</code> verfügbar.</p> + +<ol> + <li>Probieren Sie zum Beispiel diese Befehle in der Konsole aus: + <pre class="brush: js">person1.constructor +person2.constructor</pre> + + <p>Diese sollten beide den <code>Person()</code>-Konstruktor zurückgeben, da dieser die ursprüngliche Definition dieser Instanzen enthält.</p> + + <p>Ein cleverer Trick ist es, dass Sie am Ende der <code>constructor</code>-Eigenschaft Klammern setzen können (die alle erforderlichen Parameter enthalten), um eine weitere Objektinstanz aus diesem Konstruktor zu erzeugen. Der Konstruktor ist schließlich eine Funktion und kann daher mit Hilfe von Klammern aufgerufen werden; Sie müssen nur das neue Schlüsselwort einfügen, um anzugeben, dass Sie die Funktion als Konstruktor verwenden wollen.</p> + </li> + <li>Geben Sie folgendes in die Konsole ein: + <pre class="brush: js">let person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);</pre> + </li> + <li>Nun können Sie zum Beispiel auf die Funktionen Ihres neuen Objekts zuzugreifen: + <pre class="brush: js">person3.name.first +person3.age +person3.bio()</pre> + </li> +</ol> + +<p>Das funktioniert gut. Sie werden es nicht oft benutzen müssen, aber es kann wirklich nützlich sein, wenn Sie eine neue Instanz erzeugen wollen und aus irgendeinem Grund keine Referenz auf den Originalkonstruktor leicht verfügbar ist.</p> + +<p>Die <code>constructor</code>-Eigenschaft hat andere Verwendungsmöglichkeiten. Wenn Sie z.B. eine Objektinstanz haben und den Namen des Konstruktors zurückgeben wollen, von dem das Objekt eine Instanz ist, können Sie Folgendes verwenden:</p> + +<pre class="brush: js">instanceName.constructor.name</pre> + +<p>Geben Sie zum Beispiel folgendes ein:</p> + +<pre class="brush: js">person1.constructor.name +</pre> + +<div class="note"> +<p>Hinweis: Der Wert von <code>constructor.name</code> kann sich ändern (aufgrund von prototypischer Vererbung, Bindung, Präprozessoren, Transpilern, etc.), so dass Sie für komplexere Beispiele stattdessen den <code>instanceof</code>-Operator verwenden sollten.</p> +</div> + +<ol> +</ol> + +<h2 id="Prototypen_modifizieren">Prototypen modifizieren</h2> + +<p>Schauen wir uns ein Beispiel für die Veränderung der Prototyp-Eigenschaft einer Konstruktor-Funktion näher an - Methoden, die dem Prototyp hinzugefügt werden, sind dann auf allen Objektinstanzen verfügbar, die aus dem Konstruktor heraus erzeugt werden. An diesem Punkt werden wir schließlich etwas zum Prototyp unseres Konstruktors <code>Person()</code> hinzufügen.</p> + +<ol> + <li>Gehen Sie zurück zu unserem Beispiel <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> und erstellen Sie eine lokale Kopie des <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">Quellcodes</a>. Fügen Sie unter dem vorhandenen JavaScript den folgenden Code hinzu, der eine neue Methode zur Prototyp-Eigenschaft des Konstruktors hinzufügt: + + <pre class="brush: js">Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +};</pre> + </li> + <li>Speichern Sie bitte den Code, laden den Browser neu und geben bitte folgendes in die Konsole ein: + <pre class="brush: js">person1.farewell();</pre> + </li> +</ol> + +<p>Sie sollten eine Warnmeldung erhalten, die den Namen der Person, wie er im Konstruktor definiert ist, anzeigt. Das ist wirklich nützlich, aber noch nützlicher ist, dass die gesamte Vererbungskette dynamisch aktualisiert wurde, wodurch diese neue Methode automatisch auf allen vom Konstruktor abgeleiteten Objektinstanzen verfügbar ist.</p> + +<p>Denken Sie einen Moment in Ruhe darüber nach. In unserem Code definieren wir den Konstruktor, dann erzeugen wir ein Instanzobjekt aus dem Konstruktor, dann fügen wir dem Prototypen des Konstruktors eine neue Methode hinzu:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // Definition der Eigenschaften und methoden + +} + +let person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']); + +Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +};</pre> + +<p>Aber die Methode <code>farewell()</code> ist immer noch auf der <code>person1</code>-Objektinstanz verfügbar - ihre Mitglieder wurden automatisch aktualisiert, um die neu definierte Methode <code>farewell()</code> aufzunehmen.</p> + +<div class="note"> +<p>Hinweis: Sie können dazu gerne auch unsere Beispieldatei <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> nutzen (<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">hier finden Sie den Quellcode</a>), falls Ihnen der Quellcode aus dem vorangegangenen Artikel nicht mehr zur Verfügung steht bzw. Ihr Quellcode nicht funktioniert.</p> +</div> + +<p>Sie werden nur selten Eigenschaften sehen, die auf der Prototyp-Eigenschaft definiert sind, weil sie nicht sehr flexibel sind, wenn sie so definiert worden. Sie könnten zum Beispiel eine solche Eigenschaft hinzufügen:</p> + +<pre class="brush: js">Person.prototype.fullName = 'Bob Smith';</pre> + +<p>Das ist nicht sehr flexibel, da die Person vielleicht nicht so genannt wird. Es wäre viel besser, den vollen Namen aus <code>name.first</code> und <code>name.last</code> zu bilden:</p> + +<pre class="brush: js">Person.prototype.fullName = this.name.first + ' ' + this.name.last;</pre> + +<p>Dies funktioniert jedoch nicht, da sich <code>this</code> in diesem Fall auf den globalen Bereich bezieht, nicht auf den Funktionsbereich. Der Aufruf dieser Eigenschaft würde <code>undefined</code> zurückgeben. Dies funktionierte gut auf die Methode, die wir früher im Prototyp definiert haben, weil sie innerhalb eines Funktionsbereichs sitzt, der erfolgreich in den Objektinstanzbereich übertragen wird. Sie können also konstante Eigenschaften auf dem Prototyp definieren (d.h. solche, die sich nie ändern müssen), aber im allgemeinen funktioniert es besser, Eigenschaften innerhalb des Konstruktors zu definieren.</p> + +<p>In der Tat ist es üblich, für weitere Objektdefinitionen die Eigenschaften innerhalb des Konstruktors und die Methoden auf dem Prototyp zu definieren. Dies macht den Code leichter lesbar, da der Konstruktor nur die Eigenschaftsdefinitionen enthält und die Methoden in separate Blöcke aufgeteilt sind. Zum Beispiel:</p> + +<pre class="brush: js">// Konstruktor mit der Definition der Eigenschaften + +function Test(a, b, c, d) { + // property definitions +} + +// eine erste Methode wird definiert + +Test.prototype.x = function() { ... }; + +// eine zweite Methode wird definiert + +Test.prototype.y = function() { ... }; + +// etc.</pre> + +<p>Dieses Muster kann in Aktion im Beispiel der <a href="https://github.com/zalun/school-plan-app/blob/master/stage9/js/index.js">Schulplan-App von Piotr Zalewa</a> gesehen werden.</p> + +<h2 id="Zusammenfassung">Zusammenfassung</h2> + +<p><br> + Dieser Beitrag hat Objekt-Prototypen in JavaScript behandelt, einschließlich wie Prototyp-Objektketten es ermöglichen, das Objekte voneinander Funktionen (ver)erben können, sowie Prototyp-Eigenschaften und wie diese verwendet werden können, um neue Methoden zu Konstruktoren hinzuzufügen. Darüber hinaus andere mit den Themen verwandte Themen.</p> + +<p>Im nächsten Artikel sehen wir uns an, wie Sie die Vererbung von Funktionalität zwischen zwei Ihrer eigenen benutzerdefinierten Objekte implementieren können.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_diesem_Modul">In diesem Modul</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Objekt Grundlagen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Objektorientiertes JavaScript für Anfänger</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Objekt Prototypen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Vererbung in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Mit JSON Daten arbeiten</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Objekterstellungsübungen</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Funktionalität zu unserer Hüpfball Demo hinzufügen</a></li> +</ul> |