Was sind die Nuancen der prototypischen / prototypischen Vererbung von Scope in AngularJS?

1028

Auf der Seite API-Referenzbereich heißt es:

Ein Bereich kann von einem übergeordneten Bereich erben.

Auf der Seite zum Umfang des Entwicklerhandbuchs heißt es:

Ein Bereich (prototypisch) erbt Eigenschaften von seinem übergeordneten Bereich.

  • Erbt ein untergeordneter Bereich immer prototypisch von seinem übergeordneten Bereich?
  • Gibt es Ausnahmen?
  • Wenn es erbt, ist es immer eine normale prototypische JavaScript-Vererbung?
Mark Rajcok
quelle

Antworten:

1740

Schnelle Antwort :
Ein untergeordneter Bereich erbt normalerweise prototypisch von seinem übergeordneten Bereich, jedoch nicht immer. Eine Ausnahme von dieser Regel ist eine Direktive mit scope: { ... }- dies schafft einen "isolierten" Bereich, der nicht prototypisch erbt. Dieses Konstrukt wird häufig beim Erstellen einer Direktive für "wiederverwendbare Komponenten" verwendet.

Was die Nuancen betrifft, ist die Bereichsvererbung normalerweise unkompliziert ... bis Sie im untergeordneten Bereich eine bidirektionale Datenbindung (dh Formularelemente, ng-Modell) benötigen . Ng-repeat, ng-switch und ng-include können Sie auslösen, wenn Sie versuchen, innerhalb des untergeordneten Bereichs an ein Grundelement (z. B. Zahl, Zeichenfolge, Boolescher Wert) im übergeordneten Bereich zu binden . Es funktioniert nicht so, wie die meisten Leute erwarten, dass es funktionieren sollte. Der untergeordnete Bereich erhält eine eigene Eigenschaft, die die übergeordnete Eigenschaft mit demselben Namen verbirgt / schattiert. Ihre Problemumgehungen sind

  1. Definieren Sie Objekte im übergeordneten Element für Ihr Modell und verweisen Sie dann auf eine Eigenschaft dieses Objekts im untergeordneten Element: parentObj.someProp
  2. benutze $ parent.parentScopeProperty (nicht immer möglich, aber einfacher als 1. wo möglich)
  3. Definieren Sie eine Funktion im übergeordneten Bereich und rufen Sie sie vom untergeordneten Bereich aus auf (nicht immer möglich).

New AngularJS Entwickler oft nicht bewusst , dass ng-repeat, ng-switch, ng-view, ng-includeund ng-ifalle neuen untergeordneten Bereiche schaffen, so oft das Problem zeigt sich , wenn diese Richtlinien beteiligt sind. (In diesem Beispiel wird das Problem kurz veranschaulicht.)

Dieses Problem mit Grundelementen kann leicht vermieden werden, indem die "Best Practice" befolgt wird, immer ein 'zu haben.' in deinen ng-modellen - schau dir 3 minuten an. Misko demonstriert das primitive Bindungsproblem mit ng-switch.

Ein ... haben '.' In Ihren Modellen wird sichergestellt, dass die prototypische Vererbung im Spiel ist. Also, benutze

<input type="text" ng-model="someObj.prop1">

<!--rather than
<input type="text" ng-model="prop1">`
-->


Lange Antwort :

Prototypische Vererbung von JavaScript

Ebenfalls im AngularJS-Wiki platziert: https://github.com/angular/angular.js/wiki/Understanding-Scopes

Es ist wichtig, zunächst ein solides Verständnis der prototypischen Vererbung zu haben, insbesondere wenn Sie aus einem serverseitigen Hintergrund stammen und mit der klassischen Vererbung besser vertraut sind. Lassen Sie uns das zuerst überprüfen.

Angenommen, parentScope hat die Eigenschaften aString, aNumber, anArray, anObject und aFunction. Wenn childScope prototypisch von parentScope erbt, haben wir:

prototypische Vererbung

(Um Platz zu sparen, zeige ich das anArrayObjekt als einzelnes blaues Objekt mit seinen drei Werten und nicht als einzelnes blaues Objekt mit drei separaten grauen Literalen.)

Wenn wir versuchen, vom untergeordneten Bereich aus auf eine im parentScope definierte Eigenschaft zuzugreifen, sucht JavaScript zuerst im untergeordneten Bereich, nicht in der Eigenschaft, dann im geerbten Bereich und sucht die Eigenschaft. (Wenn die Eigenschaft im parentScope nicht gefunden wurde, wird die Prototypenkette bis zum Stammbereich fortgesetzt.) Das ist also alles wahr:

childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'

Angenommen, wir machen dann Folgendes:

childScope.aString = 'child string'

Die Prototypenkette wird nicht konsultiert, und dem childScope wird eine neue aString-Eigenschaft hinzugefügt. Diese neue Eigenschaft verbirgt / schattiert die gleichnamige parentScope-Eigenschaft. Dies wird sehr wichtig, wenn wir unten ng-repeat und ng-include diskutieren.

Eigentum versteckt

Angenommen, wir machen dann Folgendes:

childScope.anArray[1] = '22'
childScope.anObject.property1 = 'child prop1'

Die Prototypenkette wird konsultiert, da die Objekte (anArray und anObject) nicht im childScope gefunden werden. Die Objekte befinden sich im parentScope und die Eigenschaftswerte werden für die ursprünglichen Objekte aktualisiert. Dem childScope werden keine neuen Eigenschaften hinzugefügt. Es werden keine neuen Objekte erstellt. (Beachten Sie, dass in JavaScript Arrays und Funktionen auch Objekte sind.)

Folgen Sie der Prototypenkette

Angenommen, wir machen dann Folgendes:

childScope.anArray = [100, 555]
childScope.anObject = { name: 'Mark', country: 'USA' }

Die Prototypenkette wird nicht konsultiert, und der untergeordnete Bereich erhält zwei neue Objekteigenschaften, die die gleichnamigen parentScope-Objekteigenschaften ausblenden / schattieren.

mehr Eigentum versteckt

Imbissbuden:

  • Wenn wir childScope.propertyX lesen und childScope propertyX hat, wird die Prototypkette nicht konsultiert.
  • Wenn wir childScope.propertyX festlegen, wird die Prototypenkette nicht konsultiert.

Ein letztes Szenario:

delete childScope.anArray
childScope.anArray[1] === 22  // true

Wir haben zuerst die childScope-Eigenschaft gelöscht. Wenn wir dann erneut versuchen, auf die Eigenschaft zuzugreifen, wird die Prototypenkette konsultiert.

nach dem Entfernen eines untergeordneten Eigentums


Vererbung des Winkelbereichs

Die Anwärter:

  • Die folgenden Elemente erstellen neue Bereiche und erben prototypisch: ng-repeat, ng-include, ng-switch, ng-controller, Direktive mit scope: true, Direktive mit transclude: true.
  • Im Folgenden wird ein neuer Bereich erstellt, der nicht prototypisch erbt: Direktive mit scope: { ... }. Dadurch wird stattdessen ein "isolierter" Bereich erstellt.

Beachten Sie, dass Direktiven standardmäßig keinen neuen Bereich erstellen, dh der Standardwert ist scope: false.

ng-include

Angenommen, wir haben in unserem Controller:

$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

Und in unserem HTML:

<script type="text/ng-template" id="/tpl1.html">
<input ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div>

<script type="text/ng-template" id="/tpl2.html">
<input ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>

Jedes ng-include generiert einen neuen untergeordneten Bereich, der prototypisch vom übergeordneten Bereich erbt.

ng-include untergeordnete Bereiche

Wenn Sie (z. B. "77") in das erste Eingabetextfeld eingeben, erhält der untergeordnete Bereich eine neue myPrimitiveBereichseigenschaft, die die gleichnamige übergeordnete Bereichseigenschaft verbirgt / schattiert. Dies ist wahrscheinlich nicht das, was Sie wollen / erwarten.

ng-include mit einem Grundelement

Die Eingabe (z. B. "99") in das zweite Eingabetextfeld führt nicht zu einer neuen untergeordneten Eigenschaft. Da tpl2.html das Modell an eine Objekteigenschaft bindet, wird die prototypische Vererbung aktiviert, wenn das ngModel nach dem Objekt myObject sucht - es findet es im übergeordneten Bereich.

ng-include mit einem Objekt

Wir können die erste Vorlage, die $ parent verwendet, neu schreiben, wenn wir unser Modell nicht von einem Grundelement in ein Objekt ändern möchten:

<input ng-model="$parent.myPrimitive">

Das Eingeben (z. B. "22") in dieses Eingabetextfeld führt nicht zu einer neuen untergeordneten Eigenschaft. Das Modell ist jetzt an eine Eigenschaft des übergeordneten Bereichs gebunden (da $ parent eine untergeordnete Bereichseigenschaft ist, die auf den übergeordneten Bereich verweist).

ng-include mit $ parent

Für alle Bereiche (prototypisch oder nicht) verfolgt Angular immer eine Eltern-Kind-Beziehung (dh eine Hierarchie) über die Bereichseigenschaften $ parent, $$ childHead und $$ childTail. Normalerweise zeige ich diese Bereichseigenschaften nicht in den Diagrammen.

In Szenarien, in denen Formularelemente nicht beteiligt sind, besteht eine andere Lösung darin, eine Funktion im übergeordneten Bereich zu definieren, um das Grundelement zu ändern. Stellen Sie dann sicher, dass das untergeordnete Element immer diese Funktion aufruft, die dem untergeordneten Bereich aufgrund der prototypischen Vererbung zur Verfügung steht. Z.B,

// in the parent scope
$scope.setMyPrimitive = function(value) {
     $scope.myPrimitive = value;
}

Hier ist ein Beispiel für eine Geige , die diesen Ansatz der "übergeordneten Funktion" verwendet. (Die Geige wurde als Teil dieser Antwort geschrieben: https://stackoverflow.com/a/14104318/215945 .)

Siehe auch https://stackoverflow.com/a/13782671/215945 und https://github.com/angular/angular.js/issues/1267 .

ng-Schalter

Die Vererbung des ng-switch-Bereichs funktioniert genauso wie ng-include. Wenn Sie also eine bidirektionale Datenbindung an ein Grundelement im übergeordneten Bereich benötigen, verwenden Sie $ parent oder ändern Sie das Modell in ein Objekt und binden Sie es dann an eine Eigenschaft dieses Objekts. Dadurch wird vermieden, dass untergeordnete Bereiche die Eigenschaften des übergeordneten Bereichs ausblenden / schattieren.

Siehe auch AngularJS, Bindungsbereich eines Switch-Gehäuses?

ng-wiederholen

Ng-Repeat funktioniert etwas anders. Angenommen, wir haben in unserem Controller:

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects    = [{num: 101}, {num: 202}]

Und in unserem HTML:

<ul><li ng-repeat="num in myArrayOfPrimitives">
       <input ng-model="num">
    </li>
<ul>
<ul><li ng-repeat="obj in myArrayOfObjects">
       <input ng-model="obj.num">
    </li>
<ul>

Für jedes Element / jede Iteration erstellt ng-repeat einen neuen Bereich, der prototypisch vom übergeordneten Bereich erbt, aber den Wert des Elements auch einer neuen Eigenschaft im neuen untergeordneten Bereich zuweist . (Der Name der neuen Eigenschaft ist der Name der Schleifenvariablen.) Der Angular-Quellcode für ng-repeat lautet eigentlich wie folgt:

childScope = scope.$new();  // child scope prototypically inherits from parent scope
...
childScope[valueIdent] = value;  // creates a new childScope property

Wenn item ein Grundelement ist (wie in myArrayOfPrimitives), wird der neuen untergeordneten Bereichseigenschaft im Wesentlichen eine Kopie des Werts zugewiesen. Durch Ändern des Werts der Eigenschaft des untergeordneten Bereichs (dh unter Verwendung des ng-Modells, also des untergeordneten Bereichs num) wird das Array, auf das der übergeordnete Bereich verweist, nicht geändert. In der ersten ng-Wiederholung oben erhält jeder numuntergeordnete Bereich eine Eigenschaft, die vom Array myArrayOfPrimitives unabhängig ist:

ng-Wiederholung mit Grundelementen

Diese ng-Wiederholung funktioniert nicht (wie Sie es wollen / erwarten). Durch Eingabe in die Textfelder werden die Werte in den grauen Feldern geändert, die nur in den untergeordneten Bereichen sichtbar sind. Wir möchten, dass sich die Eingaben auf das Array myArrayOfPrimitives auswirken, nicht auf eine primitive Eigenschaft des untergeordneten Bereichs. Um dies zu erreichen, müssen wir das Modell so ändern, dass es ein Array von Objekten ist.

Wenn das Element ein Objekt ist, wird der neuen untergeordneten Bereichseigenschaft ein Verweis auf das ursprüngliche Objekt (keine Kopie) zugewiesen. Durch Ändern des Werts der Eigenschaft des untergeordneten Bereichs (dh unter Verwendung von ng-model obj.num) wird das Objekt geändert, auf das der übergeordnete Bereich verweist. In der zweiten ng-Wiederholung oben haben wir also:

ng-Wiederholung mit Objekten

(Ich habe eine Linie grau gefärbt, damit klar ist, wohin sie führt.)

Dies funktioniert wie erwartet. Durch Eingabe in die Textfelder werden die Werte in den grauen Feldern geändert, die sowohl für den untergeordneten als auch für den übergeordneten Bereich sichtbar sind.

Siehe auch Schwierigkeiten mit ng-Modell, ng-Wiederholung und Eingaben und https://stackoverflow.com/a/13782671/215945

ng-controller

Das Verschachteln von Controllern, die ng-controller verwenden, führt zu einer normalen prototypischen Vererbung, genau wie ng-include und ng-switch. Daher gelten dieselben Techniken. "Es wird jedoch als schlechte Form angesehen, wenn zwei Controller Informationen über die Vererbung von $ scope austauschen." - http://onehungrymind.com/angularjs-sticky-notes-pt-1-architecture/ Ein Dienst sollte zum Teilen von Daten zwischen verwendet werden Controller stattdessen.

(Wenn Sie Daten wirklich über die Vererbung des Controller-Bereichs freigeben möchten, müssen Sie nichts tun. Der untergeordnete Bereich hat Zugriff auf alle Eigenschaften des übergeordneten Bereichs. Siehe auch Die Ladereihenfolge des Controllers unterscheidet sich beim Laden oder Navigieren. )

Richtlinien

  1. default ( scope: false) - Die Direktive erstellt keinen neuen Bereich, daher gibt es hier keine Vererbung. Dies ist einfach, aber auch gefährlich, da beispielsweise eine Direktive den Eindruck erweckt, dass eine neue Eigenschaft im Bereich erstellt wird, obwohl tatsächlich eine vorhandene Eigenschaft überlastet wird. Dies ist keine gute Wahl, um Anweisungen zu schreiben, die als wiederverwendbare Komponenten gedacht sind.
  2. scope: true- Die Direktive erstellt einen neuen untergeordneten Bereich, der prototypisch vom übergeordneten Bereich erbt. Wenn mehr als eine Direktive (für dasselbe DOM-Element) einen neuen Bereich anfordert, wird nur ein neuer untergeordneter Bereich erstellt. Da wir eine "normale" prototypische Vererbung haben, ist dies wie ng-include und ng-switch. Seien Sie also vorsichtig bei der bidirektionalen Datenbindung an Grundelemente des übergeordneten Bereichs und beim Ausblenden / Abschatten der Eigenschaften des übergeordneten Bereichs durch den untergeordneten Bereich.
  3. scope: { ... }- Die Richtlinie schafft einen neuen isolierten / isolierten Bereich. Es erbt nicht prototypisch. Dies ist normalerweise die beste Wahl, wenn Sie wiederverwendbare Komponenten erstellen, da die Direktive den übergeordneten Bereich nicht versehentlich lesen oder ändern kann. Solche Anweisungen benötigen jedoch häufig Zugriff auf einige übergeordnete Bereichseigenschaften. Der Objekt-Hash wird verwendet, um eine bidirektionale Bindung (mit '=') oder eine einseitige Bindung (mit '@') zwischen dem übergeordneten Bereich und dem isolierten Bereich einzurichten. Es gibt auch '&' zum Binden an übergeordnete Bereichsausdrücke. Diese alle erstellen also lokale Bereichseigenschaften, die vom übergeordneten Bereich abgeleitet sind. Beachten Sie, dass Attribute zum Einrichten der Bindung verwendet werden. Sie können nicht nur auf die Namen der übergeordneten Bereichseigenschaften im Objekt-Hash verweisen, sondern müssen ein Attribut verwenden. Dies funktioniert beispielsweise nicht, wenn Sie an die übergeordnete Eigenschaft binden möchtenparentPropim isolierten Bereich: <div my-directive>und scope: { localProp: '@parentProp' }. Ein Attribut muss verwendet werden, um jede übergeordnete Eigenschaft anzugeben, an die die Direktive binden möchte: <div my-directive the-Parent-Prop=parentProp>und scope: { localProp: '@theParentProp' }.
    Isolieren Sie die __proto__Referenzen des Bereichs . $ Parent des isolierten Bereichs verweist auf den übergeordneten Bereich. Obwohl er isoliert ist und nicht prototypisch vom übergeordneten Bereich erbt, handelt es sich dennoch um einen untergeordneten Bereich.
    Für das Bild unten haben wir
    <my-directive interpolated="{{parentProp1}}" twowayBinding="parentProp2">und nehmen
    scope: { interpolatedProp: '@interpolated', twowayBindingProp: '=twowayBinding' }
    außerdem an, dass die Direktive dies in ihrer Verknüpfungsfunktion tut: scope.someIsolateProp = "I'm isolated"
    isolierter Bereich
    Weitere Informationen zu isolierten Bereichen finden Sie unter http://onehungrymind.com/angularjs-sticky-notes-pt-2-isolated-scope/
  4. transclude: true- Die Richtlinie erstellt einen neuen "transkludierten" untergeordneten Bereich, der prototypisch vom übergeordneten Bereich erbt. Der transkludierte und der isolierte Bereich (falls vorhanden) sind Geschwister - die $ parent-Eigenschaft jedes Bereichs verweist auf denselben übergeordneten Bereich. Wenn sowohl ein transkludierter als auch ein isolierter Bereich vorhanden sind, verweist die isolierte Bereichseigenschaft $$ nextSibling auf den transkludierten Bereich. Mir sind keine Nuancen mit dem übertragenen Umfang bekannt.
    Nehmen Sie für das Bild unten dieselbe Direktive wie oben mit diesem Zusatz an:transclude: true
    ausgeschlossener Umfang

Diese Geige hat eine showScope()Funktion, mit der ein isoliertes und ein ausgeschlossenes Zielfernrohr untersucht werden kann. Siehe die Anweisungen in den Kommentaren in der Geige.


Zusammenfassung

Es gibt vier Arten von Bereichen:

  1. normale Vererbung des prototypischen Bereichs - ng-include, ng-switch, ng-controller, Direktive mit scope: true
  2. normale Vererbung des prototypischen Bereichs mit einer Kopie / Zuweisung - ng-repeat. Jede Iteration von ng-repeat erstellt einen neuen untergeordneten Bereich, und dieser neue untergeordnete Bereich erhält immer eine neue Eigenschaft.
  3. Umfang isolieren - Direktive mit scope: {...}. Dieser ist nicht prototypisch, aber '=', '@' und '&' bieten einen Mechanismus für den Zugriff auf Eigenschaften des übergeordneten Bereichs über Attribute.
  4. ausgeschlossener Geltungsbereich - Richtlinie mit transclude: true. Dies ist auch eine normale Vererbung des prototypischen Bereichs, aber es ist auch ein Geschwister eines jeden isolierten Bereichs.

Für alle Bereiche (prototypisch oder nicht) verfolgt Angular immer eine Eltern-Kind-Beziehung (dh eine Hierarchie) über die Eigenschaften $ parent und $$ childHead und $$ childTail.

Diagramme wurden mit erstellt "* .dot" -Dateien, die sich auf Github befinden . Tim Caswells " Lernen von JavaScript mit Objektgraphen" war die Inspiration für die Verwendung von GraphViz für die Diagramme.

Mark Rajcok
quelle
48
Toller Artikel, viel zu lang für eine SO-Antwort, aber trotzdem sehr nützlich. Bitte fügen Sie es in Ihr Blog ein, bevor ein Editor es zuschneidet.
iwein
43
Ich habe eine Kopie in das AngularJS-Wiki gestellt .
Mark Rajcok
3
Korrektur: "Das __proto__Referenzobjekt des Bereichs isolieren." sollte stattdessen "Isolieren Sie die __proto__Referenzen des Bereichs auf ein Bereichsobjekt" lauten . In den letzten beiden Bildern sollten die orangefarbenen "Objekt" -Felder stattdessen "Bereichs" -Felder sein.
Mark Rajcok
15
Diese Antwort sollte in der eckigen Anleitung enthalten sein. Das ist weitaus didatischer ...
Marcelo De Zen
2
Das Wiki lässt mich verwirrt, zuerst heißt es: "Die Prototypenkette wird konsultiert, weil das Objekt nicht im childScope gefunden wird." und dann heißt es: "Wenn wir childScope.propertyX setzen, wird die Prototypkette nicht konsultiert." Der zweite impliziert eine Bedingung, während der erste dies nicht tut.
Stephane
140

Ich möchte in keiner Weise mit Marks Antwort konkurrieren, sondern nur das Stück hervorheben, das schließlich alles zum Klicken brachte, als jemand, der neu in der Vererbung von Javascript und seiner Prototypenkette ist .

Nur Eigenschaftslesevorgänge durchsuchen die Prototypkette, keine Schreibvorgänge. Also, wenn Sie einstellen

myObject.prop = '123';

Es sieht nicht die Kette nach, aber wenn Sie einstellen

myObject.myThing.prop = '123';

Innerhalb dieser Schreiboperation wird ein subtiler Lesevorgang ausgeführt, bei dem versucht wird, myThing nachzuschlagen, bevor auf die Requisite geschrieben wird. Deshalb wird beim Schreiben in object.properties vom Kind auf die Objekte des Elternteils zugegriffen.

Scott Driscoll
quelle
12
Obwohl dies ein sehr einfaches Konzept ist, ist es möglicherweise nicht sehr offensichtlich, da es meiner Meinung nach viele Leute vermissen. Gut ausgedrückt.
Moljac024
3
Hervorragende Bemerkung. Ich nehme weg, die Auflösung einer Nicht-Objekteigenschaft beinhaltet kein Lesen, wohingegen die Auflösung einer Objekteigenschaft dies tut.
Stephane
1
Warum? Was ist die Motivation für Immobilienschreiben, die nicht die Prototypenkette hinaufgehen? Es scheint verrückt zu sein ...
Jonathan.
1
Es wäre großartig, wenn Sie ein wirklich einfaches Beispiel hinzufügen würden.
Tylik
2
Beachten Sie, dass es funktioniert die Prototypkette für die Suche Setter . Wenn nichts gefunden wird, wird eine Eigenschaft auf dem Empfänger erstellt.
Bergi
21

Ich möchte der Antwort von @Scott Driscoll ein Beispiel für eine prototypische Vererbung mit Javascript hinzufügen. Wir werden ein klassisches Vererbungsmuster mit Object.create () verwenden, das Teil der EcmaScript 5-Spezifikation ist.

Zuerst erstellen wir die "Parent" -Objektfunktion

function Parent(){

}

Fügen Sie dann einen Prototyp zur Objektfunktion "Übergeordnet" hinzu

 Parent.prototype = {
 primitive : 1,
 object : {
    one : 1
   }
}

Erstellen Sie die Objektfunktion "Kind"

function Child(){

}

Untergeordneten Prototyp zuweisen (Kinderprototyp vom übergeordneten Prototyp erben lassen)

Child.prototype = Object.create(Parent.prototype);

Weisen Sie den richtigen "Child" -Prototypkonstruktor zu

Child.prototype.constructor = Child;

Fügen Sie einem untergeordneten Prototyp die Methode "changeProps" hinzu, die den "primitiven" Eigenschaftswert im untergeordneten Objekt neu schreibt und den Wert "object.one" sowohl im untergeordneten als auch im übergeordneten Objekt ändert

Child.prototype.changeProps = function(){
    this.primitive = 2;
    this.object.one = 2;
};

Initiieren Sie Objekte von Eltern (Vater) und Kind (Sohn).

var dad = new Parent();
var son = new Child();

Rufen Sie die changeProps-Methode Child (son) auf

son.changeProps();

Überprüfen Sie die Ergebnisse.

Die übergeordnete primitive Eigenschaft hat sich nicht geändert

console.log(dad.primitive); /* 1 */

Untergeordnete primitive Eigenschaft geändert (neu geschrieben)

console.log(son.primitive); /* 2 */

Übergeordnete und untergeordnete object.one-Eigenschaften wurden geändert

console.log(dad.object.one); /* 2 */
console.log(son.object.one); /* 2 */

Arbeitsbeispiel hier http://jsbin.com/xexurukiso/1/edit/

Weitere Informationen zu Object.create finden Sie hier https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create

tylik
quelle