Méthodes de création d'objets en JavaScript
Il existe pluseiurs approches pour instancier des objets dans ce langage.
1. Littéral objet
var vehicule = {
marque: 'Peugeot',
modele: '308'
};
2. Utilisation du constructeur intégré Object
var appareil = new Object();
appareil.type = 'Téléphone';
appareil.marque = 'Apple';
3. Fonction constructrice personnalisée
function AnimalEspece(nom, habitat) {
this.nom = nom;
this.habitat = habitat;
this.deplacement = function() {
console.log('Se déplace');
}
}
var lion = new AnimalEspece('Lion', 'Savane');
var aigle = new AnimalEspece('Aigle', 'Montagne');
console.log(lion);
lion.deplacement(); // Se déplace
aigle.deplacement(); // Se déplace
Fonctions constructrices détaillées
Une fonction devient constructrice lorsqu'elle est appelée avec le mot-clé new pour initialiser un nouvel objet. Par convention, son nom commence par une majuscule.
function ComposantElectronique(modele, tension) {
this.modele = modele;
this.tension = tension;
this.activer = function() {
console.log('Composant activé');
}
}
var composant1 = new ComposantElectronique('LED', '5V');
var composant2 = new ComposantElectronique('Capteur', '3.3V');
Les propriétés définies via this sont des membres d'instance. On peut aussi ajouter des membres statiques directement sur la fonction.
ComposantElectronique.categorie = 'Électronique';
console.log(ComposantElectronique.categorie); // Électronique
console.log(composant1.categorie); // undefined
Le mot-clé new effectue ces étapes : création d'un objet vide, liaison de this, exécution du code constructeur, puis retour de l'objet.
Le prototype des fonctions constructrices
Toute fonction constructrice possède une propriété prototype. Les méthodes définies sur cet objet sont partagées entre toutes les instances, optimisant ainsi l'utilisation mémoire.
function Participant(nom, score) {
this.nom = nom;
this.score = score;
}
Participant.prototype.jouer = function() {
console.log('Participe au jeu');
}
var joueurA = new Participant('Alice', 150);
var joueurB = new Participant('Bob', 200);
console.log(joueurA.jouer === joueurB.jouer); // true
On recommande de placer les propriétés propres à chaque instance dans la constructrice, et les méthodes communes sur le prototype.
L'attribut caché __proto__
Chaque objet possède un lien interne vers le prototype de sa constructrice, accessible via __proto__. Cela permet le mécanisme de recherche de propriétés héritées.
function Ouvrier(nom, metier) {
this.nom = nom;
this.metier = metier;
}
Ouvrier.prototype.travailler = function() {
console.log('Effectue une tâche');
}
var ouvrier1 = new Ouvrier('Claude', 'Maçon');
console.log(ouvrier1.__proto__ === Ouvrier.prototype); // true
ouvrier1.travailler(); // Effectue une tâche
La propriété __proto__ n'est pas standard pour une utilisation directe, mais interne à JavaScript pour orienter la résolution des propriétés.
La propriété constructor
L'objet prototype contient une référence constructor qui pointe vers la fonction constructrice. Lorsqu'on réassigne le prototype, il faut souvent rétablir manuellement cette référence.
function VehiculeMotorise(marque, energie) {
this.marque = marque;
this.energie = energie;
}
VehiculeMotorise.prototype = {
constructor: VehiculeMotorise, // Conservation de la référence
demarrer: function() {
console.log('Moteur allumé');
},
arreter: function() {
console.log('Moteur éteint');
}
}
var voiture = new VehiculeMotorise('Tesla', 'Électrique');
console.log(VehiculeMotorise.prototype.constructor === VehiculeMotorise); // true
Relations fondamentales
La fonction constructrice crée des instances. Chaque instance a un lien __proto__ vers le prototype. Le prototype référence à son tour la constructrice via constructor. Cette relation triangulaire est centrale à la programmation orientée objet en JavaScript.
La chaîne de prototypes
Lors de l'accès à une propriété, JavaScript consulte d'abord l'objet lui-même, puis remonte la chaîne des prototypes jusqu'à Object.prototype, et enfin null si la propriété n'est pas trouvée.
function EtreVivant(type, milieu) {
this.type = type;
this.milieu = milieu;
}
EtreVivant.prototype.respirer = function() {
console.log('Inspire et expire');
}
var plante = new EtreVivant('Végétal', 'Terrestre');
console.log(plante.respirer()); // Inspire et expire
// Chemin de recherche : plante -> EtreVivant.prototype -> Object.prototype -> null
Contexte this dans les prototypes
Dans la fonction constructrice, this fait référence à la nouvelle instance créée. À l'intérieur des méthodes du prototype, this désigne l'instance qui invoque la méthode, permettant un accès aux données propres de l'objet.
Extension des objets natifs
On peut enrichir les prototypes d'objets intégrés comme Array avec des méthodes personnalisées, sans réassigner complètement le prototype pour éviter les effets de bord.
Array.prototype.calculerSommeImpairs = function() {
var total = 0;
for (var index = 0; index < this.length; index++) {
if (this[index] % 2 !== 0) {
total += this[index];
}
}
return total;
};
var listeNumeros = [1, 2, 3, 4, 5, 6];
console.log(listeNumeros.calculerSommeImpairs()); // 9