Dans les deux articles précédents, nous avons présenté le modèle mémoire des prototypes en JavaScript et les méthodes de réécriture des prototypes, c'est-à-dire les précautions. Après avoir compris les prototypes, nous pouvons créer des objets JavaScript via des prototypes. Bien que la méthode de création basée sur un prototype puisse réaliser efficacement l’encapsulation, certains problèmes subsistent.
La création d'objets via des prototypes posera principalement deux problèmes :
1 Les valeurs d'attribut de l'objet ne peuvent pas être définies via le constructeur.
2. Lorsqu'il y a des variables de type référence dans les attributs, il peut y avoir une duplication des valeurs des variables.
Regardons l'exemple suivant :
function Person(){} Person.prototype = { constructor:Person, name:"Leon", age:22, friends:["Ada","Chris"], say:function(){ console.info(this.name+"["+this.friends+"]"); } }
Dans le code ci-dessus, nous créons une classe Person et la remplaçons via le prototype Certaines propriétés et méthodes sont définies, y compris une propriété friends, qui est un tableau de type référence. Ensuite, nous créons des objets via la classe Person. Le code est le suivant :
var p1 = new Person(); p1.name = "John"; p1.say(); //控制台输出:Jhon[Ada,Chris]
Nous créons l'objet p1 via la classe Person. Vous pouvez voir qu'il n'y a aucun moyen de définir des attributs pour l'objet p1 lors de l'utilisation. la méthode prototype pour créer des objets. Nous n'avons que L'attribut name de p1 n'est défini qu'après la création de l'objet. Appelez ensuite la méthode say() de p1, et la console affichera Jhon[Ada, Chris]. Tout est toujours normal jusqu'à présent.
Si nous ajoutons ensuite un nouvel ami à l'objet p1, le problème se posera. Le code est le suivant :
p1.friends.push("Mike"); //为p1增加一个朋友(注意这里是在原型中添加) p1.say();
Nous ajoutons un nouvel ami "Mike" à p1 via la méthode push du tableau. À l'heure actuelle, il n'y a pas d'attribut amis dans l'espace propre de l'objet p1, donc. "Mike" sera ajouté au prototype de Person, comme le montre la figure ci-dessous :
Puisque l'élément de tableau nouvellement ajouté est placé dans le prototype, tous les objets créés ultérieurement partagera cet Attribut, si on crée l'objet p2 à ce moment, il y aura aussi un "Mike" parmi ses amis. C’est un résultat que nous ne voulons pas voir.
var p2 = new Person(); //如果p1 push之后,原型中就多了一个人,p2也多了一个朋友 p2.say();
Créer des objets basés sur la combinaison de prototypes et de constructeurs
Afin de résoudre le problème ci-dessus, nous pouvons créer des objets basés sur la combinaison de prototypes et de constructeurs. Autrement dit, les propriétés sont définies dans le constructeur et les méthodes sont définies dans le prototype. Cette méthode combine efficacement les avantages des deux et constitue le moyen le plus couramment utilisé pour créer des objets en 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+"]"); } }
Toutes les propriétés des objets créés de cette manière sont stockées dans le propre espace de l'objet. À ce stade, lors de la création de l'objet, nous pouvons définir ses propres propriétés pour l'objet.
var p1 = new Person("Leon",22,["Ada","Chris"]); p1.name = "John"; p1.say(); //控制台输出: John[Ada,Chris]
Après avoir terminé le code ci-dessus, le modèle de mémoire de la classe Person et de l'objet p1 est le suivant :
À ce stade, nous will Lorsque p1 ajoute un nouvel ami, il sera ajouté à l'attribut amis dans l'espace mémoire de l'objet p1 lui-même. De cette façon, les propriétés de chaque objet sont indépendantes et n’interféreront pas les unes avec les autres.
p1.friends.push("Mike"); //为p1增加一个朋友(注意这里是在p1自己的空间中添加) p1.say(); //控制台输出: John[Ada,Chris,Mike] var p2 = new Person(); p2.say(); //控制台输出: John[Ada,Chris]
Par conséquent, lorsque vous créerez l'objet p2 maintenant, les amis de l'objet p2 ne seront que "Ada" et "Chris", mais pas "Mike".
Création d'objets à l'aide de prototypes dynamiques
Bien que la création d'objets basée sur la combinaison de prototypes et de constructeurs soit parfaite, il existe encore quelques différences entre celle-ci et la façon dont les objets sont créés dans des langages purement orientés objet : Les méthodes de classe sont définies en dehors de la classe. Afin de rendre l'objet de définition plus conforme aux exigences de la spécification orientée objet, nous pouvons placer le code prototype de la méthode de définition dans le constructeur Person. Cette méthode est appelée prototypage dynamique pour créer des objets.
// 动态原型方式 function Person(name,age,friends){ this.name = name; this.age = age; this.friends = friends; Person.prototype.say = function(){ console.info(this.name+"["+this.friends+"]"); } }
Notez que lors de l'utilisation de prototypes dynamiques pour créer des objets, nous ne pouvons pas utiliser la réécriture de prototypes lors de la définition de méthodes. Par exemple, le code suivant est erroné :
// 错误的动态原型方式 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+"]"); } } }
Création d'objets à l'aide du. La méthode de prototype dynamique aura également des problèmes, car les méthodes de la classe sont créées via Person.prototype.say, donc chaque fois qu'un objet est créé, une nouvelle méthode say() sera créée dans la mémoire. La façon de résoudre ce problème est que nous pouvons d'abord porter un jugement pour voir si la méthode Person.prototype.say existe, et la créer uniquement si elle n'existe pas, sinon elle ne sera pas créée.
// 动态原型方式 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)!