Nous savons que JS est orienté objet. Lorsqu’on parle d’orientation objet, il est inévitable d’impliquer le concept de classes. Généralement, les langages fortement typés comme C# et Java ont une syntaxe fixe pour définir les classes. La différence avec JS est qu’il peut utiliser diverses méthodes pour implémenter ses propres classes et objets. Il existe plusieurs méthodes générales d'implémentation :
1. Méthode Factory
La méthode Factory fait référence à la création d'une fonction Factory qui renvoie un type d'objet spécifique. L'exemple de code est le suivant :
fonction createCar(sColor,iDoors,iMpg)
{
var oTempCar=new Object;
oTempCar.color=sColor;
oTempCar.doors=iDoors;
oTempCar.mpg=iMpg;
oTempCar.showColor=function()
{
alert(this.color);
}
return oTempCar;
>
var oCar1=createCar("red",4,23);
var oCar2= createCar("blue", 3,25);
oCar1.showColor();
oCar2.showColor();
Chaque fois que sa fonction d'usine est appelée de cette manière, un un nouvel objet sera créé. Mais le problème est que chaque fois qu'un nouvel objet est généré, une nouvelle fonction showColor doit être créée, ce qui fait que chaque objet a sa propre version de showColor. En fait, tous les objets partagent la même fonction. Pour résoudre ce problème, les développeurs de l'objet. La méthode est définie en dehors de la fonction d'usine, puis l'objet reçoit un pointeur pointant vers cette fonction, comme suit
function showColor()
{
alert(this.color);
>
function createCar(sColor,iDoors,iMpg)
{
var oTempCar=new Object;
oTempCar.color=sColor;
oTempCar.doors=iDoors;
oTempCar.mpg=iMpg;
oTempCar.showColor=showColor;
return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();
De cette façon, vous n'avez pas besoin de créer votre propre fonction showColor pour chaque objet, mais créez simplement un pointeur vers cette fonction. Cela résout le problème fonctionnellement, mais la fonction n'aime pas les méthodes objet. Ainsi, la méthode constructeur a été introduite.
2. Méthode constructeur
Le constructeur est très similaire à la fonction d'usine. L'exemple de code est le suivant :
function Car(sColor,iDoors,iMpg)
{
this.color=sColor;
this.doors=iDoors ;
this.mpg=iMpg;
this.showColor=function()
{
alert(this.color);
}
}
var oCar1=new Car ("red",4,23);
var oCar2=new Car("blue",3,25);
Dans le constructeur, il y a aucun objet créé en interne, mais à l'aide de ce mot-clé. Lors de l'appel du constructeur à l'aide de l'opérateur new, un objet est créé avant d'exécuter la première ligne de code. Cet objet n'est accessible qu'en utilisant this. Mais quel est le problème ? Évidemment, chacun de ses objets créera également sa propre version de la fonction showColor. Pour résoudre ce problème, la méthode prototype suivante est introduite.
3. Méthode prototype
Cette méthode utilise l'attribut prototype de l'objet et peut être considérée comme la base pour en créer un nouveau. objets. Ici, un constructeur vide est utilisé pour définir le nom de la classe. Attribuez ensuite toutes les méthodes et propriétés directement à l’attribut prototype. Comme suit :
fonction Car()
{}
Car.prototype.color="red";
Car.prototype.doors=4;
Car.prototype.mpg=23;
Car.prototype.drivers=new Array( "Mike", "Sue");
Car.prototype.showColor=function()
{
alert(this.color);
}
La méthode prototype ne peut attribuer des valeurs que directement et ne peut pas initialiser la valeur de la propriété en passant des paramètres au constructeur. En utilisant cette méthode, vous rencontrerez deux problèmes. Je ne sais pas si vous l’avez remarqué. Le premier problème est qu'avec cette approche, vous devez créer chaque objet avant de pouvoir modifier la valeur par défaut de la propriété. Au lieu de cela, vous ne pouvez pas disposer directement des valeurs d'attribut dont vous avez besoin lors de la création de chaque objet. C'est ennuyeux. Le deuxième problème survient lorsque l'attribut fait référence à un objet. Il n'y a aucun problème avec le partage de fonctions, mais il y a des problèmes avec le partage d'objets. Parce que chaque instance implémente généralement son propre objet.
Comme ci-dessous :
var oCar1= new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//Sortie "Mike, Sue,Matt"
alert(oCar2.drivers);//Output "Mike, Sue, Matt"
Par conséquent, l'attribut drivers est juste un pointeur vers l'objet, donc toutes les instances en fait partager le même objet. En raison de ces problèmes, nous avons introduit la méthode suivante consistant à utiliser conjointement des constructeurs et des prototypes.
4. Approche mixte constructeur/prototype
L'idée de cette approche est d'utiliser le constructeur pour définir toutes les propriétés non fonctionnelles de l'objet (y compris les propriétés ordinaires et les propriétés pointant vers l'objet), définir les attributs de fonction (méthodes) de l'objet de manière prototype. Le résultat est que toutes les fonctions ne sont créées qu’une seule fois et que chaque objet possède sa propre instance de propriété d’objet. L'exemple de code est le suivant :
fonction Voiture(sColor,iDoors,iMpg )
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.drivers=new Array(" Mike","Sue") ;
}
Car.prototype.showColor=function()
{
alert(this.color);
}
var oCar1=new Car ("rouge",4, 23);
var oCar2=new Car("bleu",3,25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers );//Output "Mike,Sue,Matt"
alert(oCar2.drivers);//Output "Mike,Sue"
Comme le montre l'exemple de code, cette méthode résout les deux problèmes de la méthode précédente en même temps. Cependant, certains développeurs estiment encore que cette approche n’est pas parfaite.
5. Méthode de prototype dynamique
Nous savons que la plupart des langages orientés objetont des propriétés et des méthodes encapsulées visuellement. Cependant, la méthode showColor dans la méthode ci-dessus est définie en dehors de la classe. Ils ont donc conçu une approche de prototypage dynamique. L'idée de base de cette approche est la même que celle de l'approche hybride constructeur/prototype, la seule différence est l'emplacement des méthodes objets. Comme indiqué ci-dessous :
fonction Car(sColor ,iDoors,iMpg )
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.drivers=new Array("Mike", "Sue") ;
if(typeof Car._initialized=="undefined")
{
Car.prototype.showColor=function()
{
alert(this.color);
}
}
Car._initialized=true;
}
De cette façon, Car.prototype.showColor n'est créé qu'une seule fois. Avec cette dépendance, ce code ressemble davantage à une définition de classe dans d'autres langages.
6. Méthode d'usine mixte
Cette méthode est généralement une solution de contournement pour la méthode précédente. Son but est de créer de faux constructeurs qui renvoient simplement une nouvelle instance d'un autre type d'objet.
function createCar()
{
var oTempCar=new Object;
oTempCar.color="red";
oTempCar.doors=4;
oTempCar.mpg=23;
oTempCar.showColor=function()
{
alert(this.color);
};
return oTempCar;
>
var car=new Car();
Parce que dans la voiture () constructeur L'opérateur new est appelé en interne, donc le deuxième opérateur new est automatiquement ignoré. L'objet créé à l'intérieur du constructeur est renvoyé à la variable var. Cette approche pose les mêmes problèmes que l’approche classique concernant la gestion interne des méthodes objets. Il est donc fortement recommandé d’éviter d’utiliser cette méthode sauf en cas d’absolue nécessité.