Heim  >  Artikel  >  Web-Frontend  >  Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären

不言
不言nach vorne
2018-10-19 14:53:553090Durchsuche

Der Inhalt dieses Artikels befasst sich mit der detaillierten Erläuterung der JS-Prototypenkette. Ich hoffe, dass er für Freunde in Not hilfreich ist.

Mein Verständnis von js-Prototypen und Prototypketten war immer verwirrend. Nachdem ich „JavaScript Advanced Programming“ und verschiedene Artikel gelesen habe, habe ich endlich ein vorläufiges Verständnis von Prototypen und Prototypketten Um mein Verständnis für Prototypen und Prototypenketten zu vertiefen, werde ich eine Frage analysieren, auf die ich vor einiger Zeit gestoßen bin, und sie anhand meiner eigenen Ideen interpretieren.

1. Frage

Was ist das Ergebnis, wenn das folgende Programm ausgeführt wird?

rrree

B. Katze
C. Tiger

Die Antwort ist

B Katze

2. Interpretation

1. Prototypobjekt

Immer wenn eine neue Funktion erstellt wird, wird ein Prototypattribut für die Funktion gemäß einem bestimmten Satz von Regeln erstellt zum Prototypobjekt der Funktion. Standardmäßig erhalten alle Prototypobjekte automatisch ein Konstruktorattribut, das einen Zeiger auf die Funktion darstellt, in der sich das Prototypattribut befindet.

Das folgende Diagramm dient zur Veranschaulichung von

function Animal() {
    this.name = 'Animal';
}

Animal.prototype.changeName = function (name) {
    this.name = name;
}

function Cat() {
    this.name = 'Cat';
}

var animal = new Animal();

Cat.prototype = animal;
Cat.prototype.constructor = Cat;

var cat = new Cat();

animal.changeName('Tiger');

console.log(cat.name)

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklärenErstellen Sie zunächst eine Animal-Funktion. Animal enthält ein Prototypattribut, das auf Animal Prototype und Animal verweist. Prototyp. Konstruktor zeigt auf Animal. Da das Namensattribut derzeit in der Funktion definiert ist, befindet es sich nicht im Tierprototyp und die Funktion „changeName“ wird über Animal.prototype.changeName definiert, sodass wir diese Methode verwenden können, um den Prototyp beim Instanziieren mehrerer Objekte gemeinsam zu nutzen. Methode speichern.

Dasselbe gilt auch, wenn die Cat-Funktion erstellt wird.

function Animal() {
    this.name = 'Animal';
}
Animal.prototype.changeName = function (name) {
    this.name = name;
}

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären2. Eine Instanz erstellen

Wenn der Konstruktor aufgerufen wird, um eine neue Instanz zu erstellen, enthält die Instanz einen Zeiger intern (interne Eigenschaft) und zeigt auf das Prototypobjekt des Konstruktors. Dieser Zeiger wird in der 5. Ausgabe von ECMA-262 als [[Prototyp]] bezeichnet. Obwohl es keine Standardmethode für den Zugriff auf [[Prototype]] in Skripten gibt, unterstützen Firefox, Safari und Chrome ein Attribut __proto__ für jedes Objekt. Es ist wichtig klarzustellen, dass diese Verbindung zwischen der Instanz und dem Prototypobjekt des Konstruktors besteht, nicht zwischen der Instanz und dem Konstruktor.

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären

function Cat() {
    this.name = 'Cat';
}

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklärenDieser Teil entspricht dem Zeigen des Zeigers von Cats Prototypobjekt auf animal-Instanz, sodass das ursprüngliche Konstruktorattribut im Cat-Prototypobjekt verloren geht und durch die Attribute in der animal-Instanz ersetzt wird, einschließlich des Namensattributs und des internen __proto__-Attributs. Gleichzeitig zeigt das __proto__-Attribut auch auf Animal.prototype. Daher kann Cat die prototypischen Kettensuchaufrufe auch an Eigenschaften und Methoden in Animal übergeben.

// 将Cat的原型对象指向animal实例,获得animal中的属性,原有的属性丢失
Cat.prototype = animal;

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklärenDieser Teil entspricht der Neuerstellung eines Konstruktorattributs im Prototypobjekt und dem Verweisen auf den Cat-Konstruktor.

// 相当于重新创建了constructor,指向Cat构造函数
Cat.prototype.constructor = Cat;

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären3. Rufen Sie die Methode

var cat = new Cat();   // 实例化一个Cat对象,跟实例化Animal相似

auf. Wenn var animal = new Animal(); ein Animal-Objekt instanziiert, enthält Animal eine interne Eigenschaft, die auf Animal.prototype verweist; mit anderen Worten, animal hat keine direkte Beziehung zum Konstruktor Animal. Sie können jedoch sehen, dass, obwohl changeName nicht in der Instanz enthalten ist, animal.changeName(name) aufgerufen werden kann. Dies wird durch den Prozess der Suche nach den Objektattributen erreicht, das heißt:

Suchen Sie zuerst die Instanz in der Instanz Gibt an, ob es in Animal eine ChangeName-Methode gibt. Wenn nicht, fahren Sie mit der Suche fort und gehen Sie zu Animal.prototype, um herauszufinden, ob eine ChangeName-Methode vorhanden ist. Wenn ja, rufen Sie sie auf. Wenn nicht, fahren Sie mit der Suche fort und suchen Sie im Objekt. Wenn der Prototyp am Ende nicht gefunden wird, wird eine Null zurückgegeben.

Offensichtlich gibt es hier im Instanztier keine Methode „changeName“. Sie müssen also zu Animal.prototype gehen, um die Methode „changeName“ zu finden und sie aufzurufen, um das Namensattribut im Instanztier erfolgreich in „Tiger“ zu ändern.

Da Cat.prototype auf das Instanztier zeigt, ändert sich zu diesem Zeitpunkt auch das Namensattribut in Cat.prototype in Tiger.

Nehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären

console.log(cat.name)  // Cat

最后,获取cat.name,与查找方法同样,也是先去实例中cat查找是否含有name属性,在这里很明显是存在的,因此直接结束寻找,此时cat.name = 'Cat'。

三、总结

通过这道题,加深了我对原型和原型链的理解,其实这道题也可以扩展到关于继承的知识点,在JavaScript中实现继承主要是依靠原型链来实现。

Das obige ist der detaillierte Inhalt vonNehmen Sie sich mit, um die JS-Prototypkette im Detail zu erklären. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen