Heim  >  Artikel  >  Web-Frontend  >  JavaScript objektorientiert – Erstellen von Objekten basierend auf Komposition und dynamischen Prototypen

JavaScript objektorientiert – Erstellen von Objekten basierend auf Komposition und dynamischen Prototypen

黄舟
黄舟Original
2017-01-19 15:18:251218Durchsuche

In den beiden vorherigen Artikeln haben wir das Speichermodell von Prototypen in JavaScript und die Methoden zum Umschreiben von Prototypen, also Vorsichtsmaßnahmen, vorgestellt. Nachdem wir Prototypen verstanden haben, können wir JavaScript-Objekte durch Prototypen erstellen. Obwohl die prototypbasierte Erstellungsmethode die Kapselung effektiv abschließen kann, gibt es immer noch einige Probleme.

Das Erstellen von Objekten durch Prototypen verursacht hauptsächlich zwei Probleme:

  • 1 Die Attributwerte des Objekts können nicht über den Konstruktor festgelegt werden.

  • 2. Wenn Referenztypvariablen in Attributen vorhanden sind, kann es zu Duplikaten von Variablenwerten kommen.

Sehen wir uns das folgende Beispiel an:

function Person(){}
Person.prototype = {
  constructor:Person,
  name:"Leon",
  age:22,
  friends:["Ada","Chris"],
  say:function(){
    console.info(this.name+"["+this.friends+"]");
  }
}

Im obigen Code erstellen wir eine Person-Klasse und überschreiben sie durch den Prototyp. Einige Eigenschaften und Methoden werden festgelegt. einschließlich einer Friends-Eigenschaft, die ein Array vom Referenztyp ist. Als nächstes erstellen wir Objekte über die Person-Klasse. Der Code lautet wie folgt:

var p1 = new Person();
p1.name = "John";
p1.say(); //控制台输出:Jhon[Ada,Chris]

Wir erstellen Objekt p1 über die Person-Klasse. Sie können sehen, dass es bei Verwendung keine Möglichkeit gibt, Attribute für Objekt p1 festzulegen Wir haben nur die Prototyp-Methode zum Erstellen von Objekten. Das Namensattribut von p1 wird erst festgelegt, nachdem das Objekt erstellt wurde. Rufen Sie dann die Methode say() von p1 auf und die Konsole gibt Jhon[Ada, Chris] aus.

Wenn wir dann einen neuen Freund zum Objekt p1 hinzufügen, entsteht das Problem. Der Code lautet wie folgt:

p1.friends.push("Mike"); //为p1增加一个朋友(注意这里是在原型中添加)
p1.say();

Wir fügen über die Push-Methode des Arrays einen neuen Freund „Mike“ zu p1 hinzu. Zu diesem Zeitpunkt gibt es kein Friends-Attribut im eigenen Bereich des Objekts p1 „Mike“ wird zum Prototyp der Person hinzugefügt, wie in der folgenden Abbildung dargestellt:

JavaScript objektorientiert – Erstellen von Objekten basierend auf Komposition und dynamischen Prototypen

Da das neu hinzugefügte Array-Element im Prototyp platziert wird, werden alle später erstellten Objekte berücksichtigt wird dieses Attribut teilen. Wenn wir zu diesem Zeitpunkt Objekt p2 erstellen, wird es auch einen „Mike“ unter seinen Freunden geben. Das ist ein Ergebnis, das wir nicht sehen wollen.

var p2 = new Person();
//如果p1 push之后,原型中就多了一个人,p2也多了一个朋友
p2.say();

Erstellen Sie Objekte basierend auf der Kombination von Prototypen und Konstruktoren

Um das oben genannte Problem zu lösen, können wir Objekte erstellen, die auf der Kombination von Prototypen und Konstruktoren basieren. Das heißt, die Eigenschaften werden im Konstruktor und die Methoden im Prototyp definiert. Diese Methode kombiniert effektiv die Vorteile beider und ist die am häufigsten verwendete Methode zum Erstellen von Objekten in JavaScript.

function Person(name,age,friends){
  //属性在构造函数中定义
  this.name = name;
  this.age = age;
  this.friends = friends;
}
Person.prototype = {
  //方法在原型中定义
  constructor:Person,
  say:function(){
    console.info(this.name+"["+this.friends+"]");
  }
}

Alle Eigenschaften von Objekten, die auf diese Weise erstellt wurden, werden im eigenen Bereich des Objekts gespeichert. An diesem Punkt können wir beim Erstellen des Objekts seine eigenen Eigenschaften für das Objekt festlegen.

var p1 = new Person("Leon",22,["Ada","Chris"]);
p1.name = "John";
p1.say();   //控制台输出: John[Ada,Chris]

Nach Abschluss des obigen Codes ist das Speichermodell der Person-Klasse und des p1-Objekts wie folgt:

JavaScript objektorientiert – Erstellen von Objekten basierend auf Komposition und dynamischen Prototypen

Zu diesem Zeitpunkt haben wir Wenn p1 einen neuen Freund hinzufügt, wird dieser dem Attribut „friends“ im eigenen Speicherbereich des p1-Objekts hinzugefügt. Auf diese Weise sind die Eigenschaften jedes Objekts unabhängig und stören sich nicht gegenseitig.

p1.friends.push("Mike"); //为p1增加一个朋友(注意这里是在p1自己的空间中添加)
p1.say();   //控制台输出: John[Ada,Chris,Mike]
var p2 = new Person();
p2.say();   //控制台输出: John[Ada,Chris]

Wenn Sie jetzt Objekt p2 erstellen, sind die Freunde von Objekt p2 daher nur „Ada“ und „Chris“, nicht jedoch „Mike“.

Objekte mit dynamischen Prototypen erstellen

Obwohl das Erstellen von Objekten auf der Grundlage der Kombination von Prototypen und Konstruktoren perfekt ist, gibt es dennoch einige Unterschiede zur Art und Weise, wie Objekte in rein objektorientierten Sprachen erstellt werden : Klassenmethoden werden außerhalb der Klasse definiert. Um das Definitionsobjekt besser an die Anforderungen der objektorientierten Spezifikation anzupassen, können wir den Prototypcode der Definitionsmethode im Personenkonstruktor platzieren. Diese Methode zur Erstellung von Objekten wird als dynamisches Prototyping bezeichnet.

// 动态原型方式
function Person(name,age,friends){
  this.name = name;
  this.age = age;
  this.friends = friends;
   
  Person.prototype.say = function(){
    console.info(this.name+"["+this.friends+"]");
  }
}

Beachten Sie, dass wir beim Definieren von Methoden kein Prototyp-Umschreiben verwenden können, wenn wir dynamische Prototypen verwenden. Beispielsweise ist der folgende Code falsch:

// 错误的动态原型方式
function Person(name,age,friends){
  this.name = name;
  this.age = age;
  this.friends = friends;
   
  //不能使用原型重写的方式来设置方法
  Person.prototype = {
    constructor:Person,
    say:function(){
      console.info(this.name+"["+this.friends+"]");
    }
  }
}

Erstellen von Objekten mit Bei der dynamischen Prototyp-Methode treten ebenfalls Probleme auf, da die Methoden in der Klasse über Person.prototype.say erstellt werden, sodass jedes Mal, wenn ein Objekt erstellt wird, eine neue say()-Methode im Speicher erstellt wird. Die Lösung dieses Problems besteht darin, zunächst zu beurteilen, ob die Person.prototype.say-Methode vorhanden ist, und sie nur dann zu erstellen, wenn sie nicht vorhanden ist, andernfalls wird sie nicht erstellt.

// 动态原型方式
function Person(name,age,friends){
  this.name = name;
  this.age = age;
  this.friends = friends;
   
  //判断Person.prototype.say是否存在,不存在就创建
  if(!Person.prototype.say){
    alert("创建say方法");
    Person.prototype.say = function(){
      console.info(this.name+"["+this.friends+"]");
    }
  }
}

为了验证判断条件是否起作用,我们在代码中的判断分支中添加了一个弹出对话框语句。我们可以创建2个对象,然后2个对象分别调用say()方法,在结果中,第一个对象在调用say()方法时会弹出对话框,而第二个对象在调用say()方法时就不会在弹出对话框了,也就是说创建第二个对象时不会再添加say()方法。

以上就是JavaScript面向对象-基于组合和动态原型创建对象的内容,更多相关内容请关注PHP中文网(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