Javascript est un langage basé sur les objets, et presque tout ce que vous rencontrez est un objet. Cependant, il ne s’agit pas d’un véritable langage de programmation orienté objet (POO) car sa syntaxe ne comporte aucune classe.
Donc, si nous voulons encapsuler « propriété » et « méthode » dans un objet, ou même générer un objet instance à partir d’un objet prototype, que devons-nous faire ?
1. Mode original de génération d'objets
Supposons que nous considérions le chat comme un objet possédant deux attributs : « nom » et « couleur ».
var Cat = { name : '', color : '' }
Maintenant, nous devons générer deux objets instances basés sur la spécification (schéma) de cet objet prototype.
var cat1 = {}; // 创建一个空对象 cat1.name = "大毛"; // 按照原型对象的属性赋值 cat1.color = "黄色"; var cat2 = {}; cat2.name = "二毛"; cat2.color = "黑色";
D'accord, c'est l'encapsulation la plus simple, encapsulant deux propriétés dans un objet. Cependant, cette façon d'écrire présente deux inconvénients. Premièrement, si plus d'instances sont générées, il sera très difficile d'écrire. Deuxièmement, il n'y a aucun moyen de voir le lien entre les instances et le prototype.
2. Améliorations du mode original
Nous pouvons écrire une fonction pour résoudre le problème de duplication de code.
function Cat(name,color){ return { name:name, color:color } }
Ensuite, générer un objet instance équivaut à appeler une fonction :
var cat1 = Cat("大毛","黄色"); var cat2 = Cat("二毛","黑色");
Le problème avec cette méthode est toujours qu'il n'y a pas de connexion intrinsèque entre cat1 et cat2, et elle ne peut pas refléter qu'il s'agit d'instances du même objet prototype.
3. Modèle de constructeur
Afin de résoudre le problème de la génération d'instances à partir d'objets prototypes, Javascript fournit un modèle de constructeur (Constructor).
Le soi-disant « constructeur » est en fait une fonction ordinaire, mais la variable this est utilisée en interne. L'utilisation de l'opérateur new sur le constructeur générera une instance et la variable this sera liée à l'objet instance.
Par exemple, l'objet prototype de chat peut désormais s'écrire ainsi,
function Cat(name,color){ this.name=name; this.color=color; }
Nous pouvons désormais générer des objets instances.
var cat1 = new Cat("大毛","黄色"); var cat2 = new Cat("二毛","黑色"); alert(cat1.name); // 大毛 alert(cat1.color); // 黄色
À ce stade, cat1 et cat2 contiendront automatiquement un attribut constructeur pointant vers leur constructeur.
alert(cat1.constructor == Cat); //true alert(cat2.constructor == Cat); //true
Javascript fournit également un opérateur instanceof pour vérifier la relation entre les objets prototypes et les objets instance.
alert(cat1 instanceof Cat); //true alert(cat2 instanceof Cat); //true
4. Problèmes avec le modèle de constructeur
La méthode constructeur est facile à utiliser, mais il y a un problème de gaspillage de mémoire.
Veuillez voir, nous ajoutons maintenant un attribut immuable "type" (type) à l'objet Cat, puis ajoutons une méthode eat (manger des souris). Ensuite, l'objet prototype Chat devient le suivant :
function Cat(name,color){ this.name = name; this.color = color; this.type = "猫科动物"; this.eat = function(){alert("吃老鼠");}; }
Utilisez la même méthode pour générer une instance :
var cat1 = new Cat("大毛","黄色"); var cat2 = new Cat ("二毛","黑色"); alert(cat1.type); // 猫科动物 cat1.eat(); // 吃老鼠
En apparence, il ne semble y avoir aucun problème, mais en fait, il y a un gros inconvénient à faire cela. Autrement dit, pour chaque objet instance, l'attribut type et la méthode eat() ont exactement le même contenu. Chaque fois qu'une instance est générée, elle doit occuper plus de mémoire pour le contenu répété. Ce n’est ni écologique ni efficace.
alert(cat1.eat == cat2.eat); //false
L'attribut type et la méthode eat() peuvent-ils être générés une seule fois en mémoire, puis toutes les instances pointent vers cette adresse mémoire ? La réponse est oui.
5. Mode prototype
Javascript stipule que chaque constructeur possède un attribut prototype qui pointe vers un autre objet. Toutes les propriétés et méthodes de cet objet seront héritées par l'instance du constructeur.
Cela signifie que nous pouvons définir ces propriétés et méthodes immuables directement sur l'objet prototype :
function Cat(name,color){ this.name = name; this.color = color; } Cat.prototype.type = "猫科动物"; Cat.prototype.eat = function(){alert("吃老鼠")};
Ensuite, générez l'instance.
var cat1 = new Cat("大毛","黄色"); var cat2 = new Cat("二毛","黑色"); alert(cat1.type); // 猫科动物 cat1.eat(); // 吃老鼠
À l'heure actuelle, l'attribut type et la méthode eat() de toutes les instances sont en fait la même adresse mémoire, pointant vers l'objet prototype, améliorant ainsi l'efficacité opérationnelle.
alert(cat1.eat == cat2.eat); //true
6. Méthode de vérification du mode Prototype
Afin de coopérer avec l'attribut prototype, Javascript définit quelques méthodes auxiliaires pour nous aider à l'utiliser. ,
6.1 isPrototypeOf()
Cette méthode est utilisée pour déterminer la relation entre un certain objet proptotype et une instance.
alert(Cat.prototype.isPrototypeOf(cat1)); //true alert(Cat.prototype.isPrototypeOf(cat2)); //true
6.2 hasOwnProperty()
Chaque objet instance possède une méthode hasOwnProperty(), qui est utilisée pour déterminer si une certaine propriété est une propriété locale ou une propriété héritée de l'objet prototype.
alert(cat1.hasOwnProperty("name")); // true alert(cat1.hasOwnProperty("type")); // false
6,3 en opérateur
L'opérateur in peut être utilisé pour déterminer si une instance contient un certain attribut, s'il s'agit d'un attribut local ou non.
alert("name" in cat1); // true alert("type" in cat1); // true
in peut également être utilisé pour parcourir toutes les propriétés d'un objet.
for(var prop in cat1) { alert("cat1["+prop+"]="+cat1[prop]); }
Ce qui précède concerne l'encapsulation javascript. J'espère que cela sera utile à l'apprentissage de tout le monde.