Maison  >  Article  >  interface Web  >  JavaScript orienté objet - réécriture de prototypes

JavaScript orienté objet - réécriture de prototypes

黄舟
黄舟original
2017-01-19 15:14:501659parcourir

Dans l'article précédent, nous avons présenté le modèle de mémoire du prototype et analysé l'état du prototype à chaque étape à travers 4 images. Ci-dessous, nous présenterons d'abord quelques méthodes de détection de prototypes et de propriétés d'objet couramment utilisées. Prenons comme exemple la classe Person de l'article précédent. Le code pour créer la classe Person est le suivant :

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();

1 Détecter si un objet est le prototype d'une fonction

alert(Person.prototype.isPrototypeOf(p1));    //true
Cette méthode peut détecter si le prototype de p1 est Personne.

2. Détecter le constructeur d'un objet

alert(p1.constructor == Person);    //true
3. Détecter si un attribut est votre propre attribut

alert(p1.hasOwnProperty("name"));   //false
alert(p2.hasOwnProperty("name"));   //true
L'objet p1 est dans son propre espace Là. n'est pas un attribut de nom, donc false est renvoyé. L'objet p2 réaffecte l'attribut name, et l'attribut name existe dans son espace, donc il renvoie true.

4. Supprimer les attributs dans son propre espace via delete

delete p2.name;
p2.say();
alert(p2.hasOwnProperty("name")); //false
Nous pouvons utiliser delete pour supprimer un attribut dans le propre espace de l'objet, comme indiqué dans le code ci-dessus.

5. Utilisez l'attribut in pour détecter si un objet contient un certain attribut dans le prototype ou lui-même

alert("name" in p1); //在原型中有,所以为true
alert("name" in p2); //在自己的空间中有,所以为true
Si un attribut n'existe pas dans le prototype ou dans son propre espace, obtenez Le résultat est faux.

6. Méthode personnalisée pour détecter si un certain attribut existe dans le prototype

function hasPrototypeProperty(obj,prop){
  return(!obj.hasOwnProperty(prop) && (prop in obj));
}
Dans le code ci-dessus, nous avons personnalisé une méthode pour détecter si un certain attribut existe dans le prototype. Vous pouvez utiliser cette méthode comme suit :

alert(hasPrototypeProperty(p1,"name")); //true
alert(hasPrototypeProperty(p2,"name")); //false
Parce que l'attribut name de l'objet p1 existe dans le prototype, il renvoie true et l'attribut name de l'objet p2 est dans son propre espace, donc il renvoie faux.

Réécriture du prototype

Si nous écrivons le code comme avant, il y aura beaucoup d'instructions Person.prototype.xxx, ce qui n'est pas facile pour nous à lire et à comprendre. Nous pouvons réécrire le prototype dans un format de type Json. Le code est le suivant :

//重写原型
Person.prototype = {
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
var p1 = new Person();
p1.say();
Après avoir utilisé la méthode ci-dessus pour réécrire le prototype, puisque le prototype est réécrit et n'est pas spécifié via Person.prototype. , A ce moment, le constructeur ne pointe plus vers Personne, mais vers Objet.

alert(p1.constructor == Person); //false
Si le constructeur est vraiment important pour votre programme, vous pouvez déclarer le pointeur du prototype en json.

Person.prototype = {
  constructor:Person, //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
Problèmes de réécriture du prototype

Lors de la réécriture du prototype, nous pouvons rencontrer certains des problèmes suivants. Ensuite, examinons d'abord un morceau de code prototype réécrit qui posera des problèmes, puis analysons le modèle de mémoire à chaque étape du code. Le code est le suivant :

// 创建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();//报错
Dans le code ci-dessus, nous créons d'abord une classe Person. À ce stade, le modèle de mémoire du prototype Person est le suivant :

JavaScript orienté objet - réécriture de prototypes

Ensuite, nous avons créé l'objet p1, puis ajouté une méthode sayHi() au prototype Person. À l'heure actuelle, le modèle de mémoire du prototype Person est le suivant :

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

JavaScript orienté objet - réécriture de prototypes


Faites attention au modèle de mémoire actuel , car dans cet état, il n'y a pas d'attribut name dans l'espace propre de l'objet p1 ou dans le prototype Person, donc lorsque la méthode p1.sayHi() est exécutée, l'attribut this.name n'est pas défini et le résultat final de sortie n'est pas défini :Salut!.

Ensuite, nous avons réécrit le prototype Person et ajouté quelques propriétés et méthodes au prototype.

// 对Person原型进行重写
Person.prototype = {
  constructor:Person //手动指定constructor
  name:"Leon",
  age:22,
  say:function(){
    alert(this.name+ "," + this.age);
  }
}
p1.sayHi();   //输出: undefined:hi!
Le modèle de mémoire du prototype à ce moment est le suivant :

JavaScript orienté objet - réécriture de prototypes

Une fois le prototype réécrit, JavaScript allouera une nouvelle mémoire pour le prototype. La classe Person pointe vers le nouvel objet prototype, et l'attribut _proto_ de l'objet p1 initialement créé pointe toujours vers l'objet prototype précédent.

À ce moment-là, si nous exécutons p1.sayHi(), le programme ne signalera pas d'erreur, mais le résultat de l'exécution est toujours indéfini :salut !, car il n'y a pas d'attribut name dans l'objet p1 et le prototype vers lequel il pointe.

Enfin, après réécriture du prototype, nous créons l'objet p2.

var p2 = new Person();
p2.sayHi();
Le modèle de mémoire prototype à ce moment est le suivant :

JavaScript orienté objet - réécriture de prototypes

L'attribut _proto_ de l'objet p2 nouvellement créé pointe vers la réécriture If la méthode p2.sayHi() est exécutée à ce moment, il n'y aura pas de méthode sayHi() sur l'objet p2 ou le prototype vers lequel il pointe, donc le programme signalera une erreur.

Si la méthode p1.say() est exécutée à ce moment-là, puisqu'il n'y a pas de méthode say() dans p1 ou dans le prototype vers lequel elle pointe, le programme signalera une erreur.

Grâce à l'analyse du modèle de mémoire prototype ci-dessus, nous pouvons savoir que la position de réécriture du prototype affectera directement les propriétés et méthodes de l'objet. Les propriétés et méthodes de l'objet créé avant la réécriture et de l'objet créé après la réécriture sont différentes. . Même. Les diagrammes du modèle de mémoire ci-dessus doivent être gardés à l’esprit à tout moment.

Ce qui précède est le contenu de la réécriture de prototypes orientés objet JavaScript. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn