Programmation objet en JS


Retour au menu

Introduction

Pourquoi définir une classe de personne ?

Comment représenter et gérer un ensemble de N personnes, dotées d'un ensemble d'attributs comme nom, prénom, num tél, adresse complète, sexe, age, profession ...
Actuellement, il est inévitable de créer autant de tableaux de taille N que d'attributs.
 var tabNom = new Array(N);   
 var tabPrenom = new Array(N);   
 var tabAnnee_naissance = new Array(N); 
 
L'émiettement des données relatives à une personne dans de nombreux tableaux complique les traitements et apparait artificiel : que représente au fond le tableau des années de naissance ? et l'unité d'une personne tient au choix du même numéro d'indice dans tous les tableaux !

Dans la conception objet, la personne redevient le centre des préoccupations. On en fait une description générale dans la déclaration d'une classe d'objets, qui se compose de 2 parties qui décrivent ses propriétés et ses actions.


Exemple élémentaire

 
// La classe Rectangle posséde 2 propriétés
// Voici son constructeur
function Rectangle ( L, l) {
 this.largeur = l;
 this.longueur = L ;
}
// rect1 et rect2 sont des instances de la classe Rectangle.
// Les objets sont crées avec l'opérateur new.
var rect1 = new Rectangle(10 , 6)
var rect2 = new Rectangle(15 , 10.5)

// Lors de la création de rect1 par new, this est "remplacé" par rect1. 

// Exemple d'utilisation
document.write("largeur = "+ rect1.largeur)
document.write("longueur = "+ rect2.longueur)

// la fonction suivante calcule l'aire du rectangle 
function calcule_aire () {
  return this.largeur * this.longueur
}

/* On peut se servir de la fonction calcule_aire() pour intégrer 
* une méthode dans la définition de la classe Rectangle
* la méthode est appelée aire
*/
function Rectangle ( L, l)  {
 this.largeur = l ;
 this.longueur = L ; 
 this.aire = calcule_aire ; 
}	

// utilisation de la méthode
var a2 = rect2.aire())
document.write("L'aire du rectangle rect1 = "+rect1.aire() );                                          

Définition d'une classe d'objets

On choisit tout d'abord un nom identifiant la classe de l'objet, souvent commençant par une majuscule. Par exemple Personne, Voiture, Maison, Article ...
Les éléments de ces classes autrement dit les objets, seront identifiés en minuscules

Propriétés
Puis, les noms des propriétés (ou variables d'objet) qui décrivent les caractéristiques stables des objets, même si les valeurs de ces propriétés changent.
Ainsi pour Personne, les propriétés retenues peuvent être nommées : nom, prenom, adresse, codePostal, ville, numTel, annee_naissance, solde ...
A tout moment un objet, c'est-à-dire une personne particulière, possède une valeur pour chaque propriété, valeur qui peut varier au cours du temps, comme son adresse ou le solde de son compte bancaire.

Méthodes
A coté de ces caractéristiques, les méthodes de l'objet décrivent son comportement, plus précisément les traitements auquels tout objet est soumis.
Par exemple, une personne peut calculer son âge, déménager, changer de N° de téléphone, avoir son compte crédité ou débité ...et avoir un nouveau-né !
Le plus souvent, ces méthodes d'objet agissent sur les propriétés et en modifient les valeurs. Elles sont donc décrites par du code de fonction, intégré à la définition de l'objet.

Constructeur d'objets
En JS, la classe d'un objet est complètement décrite par une (seule) fonction particulière appelée constructeur de l'objet
La classe de l'objet et son constructeur portent le même nom.
Son écriture va contenir 2 parties : les déclarations des propriétés et des méthodes.

Schéma de constructeur
Le mot this, comme dans tous les langages orientés objets, permet de référencer les futurs objets de la classe.

//constructeur de la classe
function nom-classe(param1, param2 ...) {
// déclaration et initialisation des propriétés
this.propriété1 = param1 ;
this.propriété2 = param2 ;
........
// affectation des méthodes
this.méthode1 = fonction1 ;
........
}

Exemple de constructeur de Personne

//déclaration des fonctions-méthodes, elles peuvent suivre la fonction-constructeur
function calculer_age() {
.....
}
function mouvement_compte() {
.....
} 
function nouvelle_naissance() {
.....
}
// Constructeur de l'objet Personne
function Personne(n, p, ad, cp, v, t, a, nb) {
// Definition des propriétés
this.nom = n ; this.prenom = p ;	
this.adresse=ad ; this.codePostal=cp; this.ville=v; this.numTel=t;	
this.annee_naissance = a; this.nb_enfant = nb ;

// Définition des méthodes		
this.age = calculer_age ;
this.compte = mouvement_compte ;
this.naissance = nouvelle_naissance;
}

Utilisation de la classe d'objets

Construction d'objets
La classe d'objets étant décrite dans la fonction constructeur (plus les fonctions annexes, pour les méthodes de l'objet), comment l'utiliser ?
On doit distinguer 2 étapes :
  1. création des objets
  2. accès, modification de leurs propriétés, appel à leurs méthodes

Cette classe est une sorte de modèle selon lequel on va pouvoir créer des objets concrets, manipulables.
Ces objets concrets _ exemplaires tirés du modèle_ s'appellent les instances de la classe.

Pour créer une telle instance, on effectue un appel à l'aide de l'opérateur new au constructeur de l'objet, et on affecte le résultat à un identificateur de variable.
(Remarque : newa déjà été utilisé dans ce rôle pour créer des objets du type Date, Array.. )

Ecriture générale
var instance1 = new nom-classe(liste de valeurs)
Les valeurs passées en paramètre vont affecter les propriétés de l'instance (et ainsi les initialiser), conformément au code du constructeur : ils doivent donc correspondre exactement, en place et en nombre, aux paramètres formels du constructeur.
Mais on peut alternativement appeler le constructeur par défaut, sans paramètre, reportant à plus tard l'initialisation des propriétés.

Exemple : création et utilisation d'instances de Personne

// création et initialisation complète d'une instance
var p = new Personne('Toto','Jules',1,'10 rue V.Hugo','93000','Bobigny','01222222',1950,3);
// ou création, puis initialisation d'une instance
 var p = new Personne();
 p.prenom= "Jules";
 p.nom= "Toto";
 .........


Prolongements

  1. Tableau d'objets
  2. Le type tableau en JS admet tout type d'éléments. On peut donc remplir un tableau de Personne
    var personnes = new Array (N);
    for (var i=0; i<personnes.length; i++)
    	personnes[i] = new Personne();
    personnes[0].nom = "Toto";
    ....... 
    

  3. Utilisation de fichier de code .js
  4. Pour connaitre une classe
  5. Pour connaitre les propriétés/méthodes d'un objet, on peut utiliser une fonction qui parcourera toutes ses propriétés, comme nous l'avons déjà fait pour les objets prédéfinis window, document ..
    <SCRIPT LANGUAGE="JavaScript">
    function  proprietes(objet,nom) {
    var texte = "";
     for (var i in objet )
     texte +=nom+"."+i+" = " +objet[i] +"
    "; document.write(texte) } // parcours des propriétés des instances de Personne for (var i=0; i<personnes.length; i++) proprietes(personnes[i], personnes[i].nom) </SCRIPT>

  6. Classe définie à l'aide d'autres classes
  7. Soient 2 classes ClasseA et ClasseB. On suppose que :
    ClasseB contienne une propriété de "type" ClasseA, ou plus exactement qu'une de ses propriétés soit construite par affectation d'une instance de ClasseA.
    function ClasseA( n, ........) {
    // Definition des propriétés de ClasseA
    this.nom = n;
    ...........
    }
    
    function ClasseB( a, b, objetA, ....) {
    // Definition des propriétés de Classe2
    this.ppa = a;
    this.ppb = b;
    // objetA sera remplacé à la construction par
    // une instance existante de la ClasseA
    this.ppc = objetA;
    ...........
    }
    var instA = new ClasseA( ...);
    var instB = new ClasseB( aa, bb, instA, ...);
    
    document.write('La valeur de la ppté ppc de instB est : ',
    	 instB.instA.ppc);
    
    Exemple
    Soit une classe Voiture dotée des propriétés suivantes :
    function Voiture(ma, mo, a, p) {
    this.marque=ma;
    this.modele=mo;
    this.annee=a;
    // le proprietaire est implicitement un "objet" de type Personne !
    this.proprietaire = p; // p sera une instance de Personne
    this.presenter=presenter_voiture;
    }
    
    var toto = new Personne('Toto', 'Jules', .....);
    toto.presenter();
    // Par cette construction, la propriété proprietaire devient une instance de Personne !
    var auto = new Voiture('Renault','Clio',1997, toto);
    
    // Maintenant posons quelques questions importantes ! 
    // toto et auto se présentent avec leur méthodes particulières
    toto.presenter();
    auto.presenter();
    // combien d'enfants a le propriétaire de auto ?
    document.write('Le propriétaire de la voiture auto a ',
    	auto1.proprietaire.nb_enfant ,' enfant(s)');
    // quel est l'âge du propriétaire de (l') auto  ?
    document.write('Voici l\'âge du propriétaire de la voiture auto : ',
    	auto.proprietaire.age());
    // mais laissons le  propriétaire de auto se présenter lui-même !
    document.write('Présentons l\'heureux propriétaire de la voiture auto');
        	auto1.proprietaire.presenter();
    

  8. La propriété prototype
  9. Cette propriété spéciale s'applique à une classe déjà construite et permet de lui ajouter de nouvelles propriétés et méthodes
    On peut effectuer ces ajouts sur des classes prédéfinies ou définies par le programmeur
    Il faudra ensuite attribuer une valeur à cette propriété, car on ne dispose pas d'un constructeur d'objet qui l'intégre. Syntaxe
    nomClasse.prototype.nomPropriété = valeurInitiale ;

    Exemples

    1. ajout d'une propriété sexe à la classe Personne
      Personne.prototype.sexe = "f" ;
    2. ajout d'une méthode à la classe String

    <SCRIPT>
    // ajout d'une méthode à la classe String
    function fin() {
    return this.charAt(this.length-1);
    }
    String.prototype.fin = fin ;
    </SCRIPT>
    </HEAD>
    
    <BODY>
    <SCRIPT>
    var ch1 = "Bonjour à tous"
    var ch2 = "et à demain !"
    document.write("Le dernier caractère de "+ "\""+ ch1+ "\"" + " : "+ch1.fin()+"<br>");
    document.write("Le dernier caractère de "+ "\""+ ch2+ "\"" + " : "+ch2.fin()+"<br>");
    </SCRIPT>
    </BODY>