Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung des Javascript-Prototyps und der Prototypenkette

Detaillierte Erläuterung des Javascript-Prototyps und der Prototypenkette

小云云
小云云Original
2018-03-20 09:46:161388Durchsuche

Jede von uns erstellte Funktion verfügt über ein Prototypattribut. Dieses Attribut ist ein Zeiger, der auf ein Prototypobjekt zeigt, und die Eigenschaften und Methoden in diesem Prototypobjekt können von allen Instanzen gemeinsam genutzt werden. Dieser Artikel bietet Ihnen hauptsächlich eine detaillierte Analyse der relevanten Wissenspunkte und den Nutzungsaustausch von JavaScript-Prototypen und Prototypketten. Ich hoffe, er kann Ihnen helfen.

function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true

1. Prototypobjekte verstehen

Immer wenn eine neue Funktion erstellt wird, wird für die Funktion eine neue Funktion gemäß einem bestimmten Regelsatz erstellt. Prototypeigenschaft, diese Eigenschaft verweist auf das Prototypobjekt der Funktion.

Standardmäßig erhalten alle Prototypobjekte automatisch eine Konstruktoreigenschaft, die einen Zeiger auf die Funktion enthält, in der sich die Prototypeigenschaft befindet.

Wenn ein Konstruktor aufgerufen wird, um eine neue Instanz zu erstellen, enthält die Instanz einen Zeiger (interne Eigenschaft), der auf das Prototypobjekt des Konstruktors zeigt. ECMA-262 Version 5 bezeichnet diesen Zeiger als [[Prototyp]].

Obwohl es in Skripten keine Standardmethode für den Zugriff auf [[Prototype]] gibt, unterstützen Firefox, Safari und Chrome in anderen Implementierungen ein Attribut __proto__; dieses Attribut ist für Skripte jedoch nicht vollständig verfügbar unsichtbar.

Der wirklich wichtige Punkt, der klargestellt werden muss, ist jedoch, dass die Verbindung zwischen der Instanz und dem Prototypobjekt des Konstruktors besteht, nicht zwischen der Instanz und dem Konstruktor.

Am Beispiel des vorherigen Codes, der den Person-Konstruktor und Person.prototype zum Erstellen einer Instanz verwendet, zeigt Abbildung 6-1 die Beziehung zwischen den einzelnen Objekten.

Hier zeigt Person.prototype auf das Prototypobjekt und Person.prototype.constructor zurück auf Person .

Sowohl person1 als auch person2 enthalten eine interne Eigenschaft, die nur auf Person.prototype verweist, mit anderen Worten, sie haben keine direkte Beziehung zum Konstruktor.

Sie können person1.sayName() aufrufen. Dies wird durch den Prozess der Suche nach Objekteigenschaften erreicht. (Zuerst wird nach der Instanz gesucht, und wenn sie nicht gefunden werden kann, wird weiter nach dem Prototyp gesucht.)


用isPrototypeOf()方法判断实例与原型对象之间的关系
alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true

用Object.getPrototypeOf() 方法返回实例的原型对象
alert(Object.getPrototypeOf(person1) == Person.prototype); //true

使用 hasOwnProperty() 方法可以检测一个属性是存在于实例中,还是存在于原型中。
alert(person1.hasOwnProperty("name")); //false  来着原型
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person1.hasOwnProperty("name")); //true

2. Einfacher Prototyp-Syntax

Im vorherigen Beispiel muss Person.prototype jedes Mal eingegeben werden, wenn Sie ein Attribut und eine Methode hinzufügen. Um unnötiges Tippen zu reduzieren und die Funktionalität des Prototyps besser visuell zu kapseln, ist es üblicher, das gesamte Prototypobjekt mit einem Objektliteral zu überschreiben, das alle Eigenschaften und Methoden enthält.


function Person(){
}
Person.prototype = {
  name : "Nicholas",
  age : 29,
  job: "Software Engineer",
  sayName : function () {
    alert(this.name);
  }
};

Im obigen Code setzen wir Person.prototype gleich einem neuen Objekt, das als Objektliteral erstellt wurde. Das Endergebnis ist dasselbe, mit einer Ausnahme: Die Konstruktoreigenschaft zeigt nicht mehr auf Person .

Wie bereits erwähnt, wird jedes Mal, wenn eine Funktion erstellt wird, gleichzeitig ihr Prototypobjekt erstellt, und dieses Objekt erhält automatisch auch die Konstruktoreigenschaft.


var friend = new Person();
alert(friend instanceof Object); //true
alert(friend instanceof Person); //true
alert(friend.constructor == Person); //false
alert(friend.constructor == Object); //true

Hier gibt die Verwendung des Instanzoperators zum Testen von Objekt und Person immer noch „true“ zurück, aber die Konstruktoreigenschaft ist gleich „Objekt“ und nicht gleich „Person“.

Wenn der Wert des Konstruktors wirklich wichtig ist, können Sie ihn wie unten beschrieben gezielt auf den entsprechenden Wert zurücksetzen.


function Person(){
}
Person.prototype = {
  constructor : Person,
  name : "Nicholas",
  age : 29,
  job: "Software Engineer",
  sayName : function () {
    alert(this.name);
  }
};

3. Prototypen nativer Objekte

Alle nativen Referenztypen (Objekt, Array, String usw.) Alle Methoden werden im Prototyp ihres Konstruktors definiert.

Zum Beispiel ist die Methode sort() in Array.prototype und die Methode substring() in String.prototype zu finden. Obwohl dies möglich ist, wird es nicht empfohlen, den Prototyp eines nativen Objekts zu ändern.

4. Probleme mit Prototypobjekten

Das größte Problem mit dem Prototypmuster wird durch seine gemeinsame Natur verursacht. Die Änderung einer davon wirkt sich auf die andere aus.


function Person(){
}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby", "Court"],
sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court,Van"
alert(person1.friends === person2.friends); //true

5. Prototypenkette

Die Grundidee besteht darin, Prototypen zu verwenden, um einen Referenztyp einen anderen Referenztyp erben zu lassen . Eigenschaften und Methoden. Anschließend entsteht Schicht für Schicht eine Kette von Instanzen und Prototypen. Dies ist das Grundkonzept der sogenannten Prototypenkette.


function SuperType(){
  this.property = true;
}
SuperType.prototype.getSuperValue = function(){
  return this.property;
};
function SubType(){
  this.subproperty = false;
}
//继承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
  return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true

Ein Bild zeigt:

Eigenschaft befindet sich in SubType.prototype. Dies liegt daran, dass es sich bei der Eigenschaft um eine Instanzeigenschaft und bei getSuperValue() um eine Prototypmethode handelt. Da SubType.prototype nun eine Instanz von SuperType ist, befindet sich die Eigenschaft natürlich in dieser Instanz.

Verwandt:

Detaillierte Erklärung des js-Prototyps und der Prototypenkette


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Javascript-Prototyps und der Prototypenkette. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn