Heim  >  Artikel  >  Web-Frontend  >  JavaScript objektorientiert – Umschreiben von Prototypen

JavaScript objektorientiert – Umschreiben von Prototypen

黄舟
黄舟Original
2017-01-19 15:14:501605Durchsuche

Im vorherigen Artikel haben wir das Speichermodell des Prototyps vorgestellt und den Status des Prototyps in jeder Phase anhand von 4 Bildern analysiert. Im Folgenden stellen wir zunächst einige häufig verwendete Methoden zur Erkennung von Prototypen und Objekteigenschaften vor. Nehmen wir als Beispiel die Person-Klasse aus dem vorherigen Artikel. Der Code zum Erstellen der Person-Klasse lautet wie folgt:

function Person(){};
 
Person.prototype.name = "Leon";
Person.prototype.age = 22;
Person.prototype.say = fucntion(){
  alert(this.name + "," + this.age);
}
 
var p1 = new Person();
var p2 = new Person();
p2.name = "Ada";
 
p1.say();
p2.say();

Erkennen Sie, ob ein Objekt der Prototyp einer Funktion ist

alert(Person.prototype.isPrototypeOf(p1));    //true

Diese Methode kann erkennen, ob der Prototyp von p1 eine Person ist.

2. Erkennen Sie den Konstruktor eines Objekts

alert(p1.constructor == Person);    //true

3. Erkennen Sie, ob ein Attribut Ihr eigenes Attribut ist

alert(p1.hasOwnProperty("name"));   //false
alert(p2.hasOwnProperty("name"));   //true

Objekt p1 befindet sich in seinem eigenen Raum ist kein Namensattribut, daher wird false zurückgegeben. Das Objekt p2 weist das Namensattribut neu zu und das Namensattribut ist in seinem Bereich vorhanden, sodass es true zurückgibt.

4. Attribute im eigenen Bereich durch Löschen löschen

delete p2.name;
p2.say();
alert(p2.hasOwnProperty("name")); //false

Wir können Löschen verwenden, um ein Attribut im eigenen Bereich des Objekts zu löschen, wie im obigen Code gezeigt.

5. Verwenden Sie das in-Attribut, um zu erkennen, ob ein Objekt ein bestimmtes Attribut im Prototyp oder in sich selbst enthält.

alert("name" in p1); //在原型中有,所以为true
alert("name" in p2); //在自己的空间中有,所以为true

Wenn ein Attribut im Prototyp oder in seinem eigenen Bereich nicht vorhanden ist, rufen Sie es ab Das Ergebnis ist falsch.

6. Benutzerdefinierte Methode zur Erkennung, ob ein bestimmtes Attribut im Prototyp vorhanden ist

function hasPrototypeProperty(obj,prop){
  return(!obj.hasOwnProperty(prop) && (prop in obj));
}

Im obigen Code haben wir eine Methode angepasst, um zu erkennen, ob ein bestimmtes Attribut im Prototyp vorhanden ist. Sie können diese Methode wie folgt verwenden:

alert(hasPrototypeProperty(p1,"name")); //true
alert(hasPrototypeProperty(p2,"name")); //false

Da das Namensattribut des p1-Objekts im Prototyp vorhanden ist, gibt es true zurück und das Namensattribut des p2-Objekts befindet sich in einem eigenen Bereich, also ist es gibt false zurück.

Umschreiben des Prototyps

Wenn wir den Code wie zuvor schreiben, wird es viele Person.prototype.xxx-Anweisungen geben, die für uns nicht leicht zu lesen und zu verstehen sind. Wir können den Prototyp in einem Json-ähnlichen Format umschreiben. Der Code lautet wie folgt:

//重写原型
Person.prototype = {
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
var p1 = new Person();
p1.say();

Nachdem wir die obige Methode zum Umschreiben des Prototyps verwendet haben, wird der Prototyp neu geschrieben und nicht über Person.prototype angegeben Zu diesem Zeitpunkt zeigt der Konstruktor nicht mehr auf Person, sondern auf Objekt.

alert(p1.constructor == Person); //false

Wenn der Konstruktor für Ihr Programm wirklich wichtig ist, können Sie den Prototypzeiger in JSON deklarieren.

Person.prototype = {
  constructor:Person, //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}

Probleme beim Umschreiben des Prototyps

Beim Umschreiben des Prototyps können einige der folgenden Probleme auftreten. Schauen wir uns als Nächstes zunächst einen Teil des neu geschriebenen Prototypcodes an, der Probleme verursachen wird, und analysieren wir dann das Speichermodell in jeder Phase des Codes. Der Code lautet wie folgt:

// 创建Person类
function Person(){}
 
var p1 = new Person();
//在Person的原型上添加了sayHi()方法
Person.prototype.sayHi = function(){
  alert(this.name + "Hi!");
}
p1.sayHi();   //输出: undefined:hi!
 
// 对Person原型进行重写
Person.prototype = {
  constructor:Person, //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
 
var p2 = new Person();
p2.sayHi();
 
p2.say();//正确
p1.say();//报错

Im obigen Code erstellen wir zunächst eine Person-Klasse. Zu diesem Zeitpunkt sieht das Speichermodell des Person-Prototyps wie folgt aus:

JavaScript objektorientiert – Umschreiben von Prototypen

Dann haben wir das p1-Objekt erstellt und dann eine sayHi()-Methode zum Person-Prototyp hinzugefügt. Zu diesem Zeitpunkt ist das Speichermodell des Personenprototyps wie folgt:

var p1 = new Person();
//在Person的原型上添加了sayHi()方法
Person.prototype.sayHi = function(){
  alert(this.name + "Hi!");
}
p1.sayHi();   //输出: undefined:hi!

JavaScript objektorientiert – Umschreiben von Prototypen


Achten Sie auf das aktuelle Speichermodell Denn in diesem Zustand gibt es kein Namensattribut im eigenen Bereich des p1-Objekts oder im Personenprototyp. Wenn also die Methode p1.sayHi() ausgeführt wird, ist das Attribut this.name undefiniert und das endgültige Ausgabeergebnis ist undefiniert :Hi!.

Als nächstes haben wir den Person-Prototyp neu geschrieben und dem Prototyp einige Eigenschaften und Methoden hinzugefügt.

// 对Person原型进行重写
Person.prototype = {
  constructor:Person //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
p1.sayHi();   //输出: undefined:hi!

Das Prototyp-Speichermodell sieht zu diesem Zeitpunkt wie folgt aus:

JavaScript objektorientiert – Umschreiben von Prototypen

Nachdem der Prototyp neu geschrieben wurde, weist JavaScript einen neuen Speicher für zu Prototyp. Die Person-Klasse zeigt auf das neue Prototyp-Objekt und das _proto_-Attribut des ursprünglich erstellten p1-Objekts zeigt weiterhin auf das vorherige Prototyp-Objekt.

Wenn wir zu diesem Zeitpunkt p1.sayHi() ausführen, meldet das Programm keinen Fehler, aber das Ausführungsergebnis ist immer noch undefiniert:hi!, da das p1-Objekt kein Namensattribut enthält und das Prototyp, auf den es hinweist.

Schließlich erstellen wir nach dem Umschreiben des Prototyps das Objekt p2.

var p2 = new Person();
p2.sayHi();

Das Prototyp-Speichermodell ist zu diesem Zeitpunkt wie folgt:

JavaScript objektorientiert – Umschreiben von Prototypen

Das _proto_-Attribut des neu erstellten p2-Objekts zeigt auf das Umschreibe-If Die p2.sayHi()-Methode wird zu diesem Zeitpunkt ausgeführt. Es gibt keine sayHi()-Methode für das p2-Objekt oder den Prototyp, auf den es verweist, sodass das Programm einen Fehler meldet.

Wenn die p1.say()-Methode zu diesem Zeitpunkt ausgeführt wird, meldet das Programm einen Fehler, da es in p1 oder dem Prototyp, auf den es verweist, keine say()-Methode gibt.

Durch die Analyse des Prototyp-Speichermodells können wir erkennen, dass sich die Position des Prototyp-Umschreibens direkt auf die Eigenschaften und Methoden des Objekts auswirkt, die vor dem Umschreiben erstellt wurden, und die Eigenschaften und Methoden, die nach dem Umschreiben erstellt wurden . Die obigen Speichermodelldiagramme müssen jederzeit im Auge behalten werden.

Das Obige ist der Inhalt des objektorientierten JavaScript-Prototyp-Umschreibens. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).


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