2016-04-08 13 views
3

mit habe ich diese Konstruktorfunktion Person:einen Prototyp Aktualisieren einer Instanz in JavaScript

function Person(name) { 
    this.name = name; 
} 

ich ein Array hinzugefügt favorites auf dem dessen Prototyp so, dass alle Instanzen von Person auf demselben Array zeigen kann:

Person.prototype.favorites = []; 
var person1 = new Person("KimK"); 
var person2 = new Person("KhloeK"); 

person1.favorites = ["coke"]; 
person2.favorites = ["pepsi"]; 

console.log(person1.favorites); //["coke"] 
console.log(person2.favorites); //["pepsi"] 

ich erwartet, dass die beiden Protokoll Aussagendruckenseit person1 und person2 zeigen auf das gleiche Basis-Array favorites auf dem Prototyp, und seit person2 geändert, um schließlich ["pepsi"], erwartete ich beide Ausgänge ["pepsi"]. Fehle ich etwas?

+0

Es ist unmöglich, weil Person 1 & Person 2 zwei verschiedene Instanzen sind! –

Antwort

3

Das Lesen von Objekteigenschaften kann das Durchsuchen der Vererbungskette erfordern.

Das Lesen einer JavaScript-Objekteigenschaft durchsucht zuerst die lokalen Eigenschaftsnamen des Objekts. Wenn nicht als lokale oder "own" property gefunden, wird die Suche fortgesetzt, indem nacheinander jedes Prototypobjekt in der Vererbungskette betrachtet wird, bis der Eigenschaftsname gefunden wird oder alle Objekte in der Vererbungskette untersucht wurden. Wenn der Name gefunden wurde, wird sein Wert von dem Objekt erhalten, in dem er gefunden wurde. Wenn nicht gefunden, wird undefined als benannter Eigenschaftswert zurückgegeben.

Schreiben Objekteigenschaften immer * schreibt Eigenschaftswerte lokal

den Wert eines benannten Wert Eigenschaft Schreiben erstellt oder aktualisiert einen lokalen Wert Eigenschaft durch das Objekt gehalten wird geschrieben. Wenn es zuvor über die Vererbungskette vererbt wurde, wird es nicht mehr vererbt: reading gibt den lokalen Wert als Präferenz zurück. Beachten Sie, dass der geerbte Eigenschaftswert des Objekts, von dem er geerbt wurde, unverändert bleibt.

So

person1.favorites = ["coke"]; 
person2.favorites = ["pepsi"]; 

erstellt eine neue lokale favorites Eigenschaft person1 vor ["coke"], um es, und eine neue lokale favorites Eigenschaft person2 schriftlich vor ["pepsi"], um es zu schreiben.

Ein vorheriger favorites Eigenschaftswert, geerbt von Person.prototype, [], wird im Prozess ausgeblendet.


* Getters und Setters in ES5 definiert ausgeschlossen

Setter und getter Funktionen einen Eigenschaftsnamen mit einem Objekt zuzuordnen. Eigenschaftsnamen, die auf diese Weise eingerichtet sind, haben keinen internen Slot [[Wert]], sind aber als Getter- und Setter-Funktionen vererbbar. Insbesondere das Schreiben in ein Objekt durchsucht die Vererbungskette nach einem Setter, wenn eine lokale Eigenschaft mit demselben Namen noch nicht existiert.

Obwohl Getter und Setter mit dem gelesenen oder geschriebenen Objekt als this-Wert aufgerufen werden, kann nicht verallgemeinert werden, wo und wie sie Werte speichern und abrufen, da dies davon abhängt, wie sie geschrieben werden.

+0

'" Das Schreiben von Objekteigenschaften schreibt immer Eigenschaftswerte lokal "'. Beachten Sie, dass es eine Ausnahme gibt, wenn die Eigenschaft des Prototyps ein [Setter] ist (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/set). – Paulpro

+0

@Paulpro danke für den Hinweis - Ich habe die Antwort aktualisiert, um Änderungen an dem in ES5 erstellten Modell abzudecken. – traktor53

1

Wenn Sie ["coke"]-person1.favorites sind zuweisen, sind Sie eine Eigenschaft von person1 ändern, nicht die Person Prototyp. Sie können dies leicht überprüfen, indem Sie console.log(Person.prototype.favorites) — es enthält leeres Array. Wenn Sie den Wert für alle Instanzen ändern wollen, ist der einzige Weg, um direkt den Prototyp zu ändern, das heißt:

Person.prototype.favorites = ["coke"]; 

Wenn Sie jedoch keine favorites Eigenschaft auf Person Instanzen festgelegt haben, können Sie den Prototyp ändern durch Modifizieren person1.favorites. Beispiel:

function Person(name) { 
    this.name = name; 
} 
Person.prototype.favorites = []; 

var person1 = new Person("KimK"); 
person1.favorites.push("coke", "pepsi") 

console.log(person1.favorites); // ["coke", "pepsi"] 

var person2 = new Person("KhloeK"); 
console.log(person2.favorites); // ["coke", "pepsi"] 

console.log(Person.prototype.favorites); // ["coke", "pepsi"] 
+0

danke für console.log (Person.prototype.favorites), ich habe Sie upvoted, um den Downvote zu neutralisieren, ich glaube, wir können immer noch das Array auf dem Prototyp mit einer Instanz mit Push-Methode auf dem Array ändern –

+0

@WildWidow Nein, Sie Prototyp kann nicht durch Ändern einer Instanz geändert werden. Wie auch immer, für was willst du es? –

+0

person1.favorites.push ('coke'); - Erstellt keine neuen Favoriten in der person1-Instanz, stattdessen geht es zum Favoriten-Array auf dem Prototyp. Das bedeutet, dass wir den Prototyp durch eine Instanz modifizieren, richtig? –

2

Hiermit wird der Favoriteneigenschaft von person1 ein neues Array zugewiesen. Es verändert nicht die bestehende auf dem Prototyp:

person1.favorites = ["coke"]; 

Sie auf ein Array Drück anhängen und Sie können ein Array leer durch seine Länge auf 0 Als Beispiel voran:

person1.favorites.push('coke'); 
person2.favorites.length = 0;   
person2.favorites.push('coke'); 
+0

Große Antwort, durch die Verwendung von push(), warum es kein neues Array auf der Instanz erstellt? –

+0

@WildWidow Push ändert das Array, anstatt ein neues zu erstellen. – Paulpro

+0

also können wir den Prototyp mit einer Instanz ändern, oder? –