JavaScript est un langage Objet. L'approche est maintenant généralisée dans tous les langages de programmation. Car elle permet de développer des scritps efficaces, réutilisables et facilement évolutifs et paramétrables.
Cette page présente les principes généraux de la programmation objet en JavaScript.
Un objet au sens de la programmation est un ensemble structuré de différentes données et de fonctionnalités.
Les objets spécifiques au JavaScript sont détaillés dans la référence du langage.
Pour créer un nouvel objet, on utilise l'instruction new et on ajoute soit un type d'objet prédéfini (comme Object, Date, Array, ...), soit une fonction, appelée constructeur, qui permet de créer les propriétés de cet objet.
Créons notre premier constructeur d'objet :
function CreerChien(le_nom, la_race) { this.nom=le_nom; this.race=la_race; } var mon_chien = new CreerChien("Rex", "Berger allemand"); console.log(mon_chien);
La fonction CreerChien() fait appel au mot this qui représente l'objet en cours de manipulation par le constructeur.
La propriété constructor retourne la fonction constructeur de l'objet.
document.write("mon_chien.constructor = "+mon_chien.constructor.name);
Le name
de constructor de mon_chien
est affiché :
La variable mon_chien est maintenant une instance d'objet de type chien qui contient les propriétés nom et race. Naturellement, il est possible de rajouter des propriétés très facilement, sans se soucier des questions d'indices qu'imposerait un tableau du type :
mon_chien[0]="Rex"; mon_chien[1]="Berger allemand";
La conception Objet permet de plus d'accéder intuitivement aux propriétés des objets, par la notation pointée. Pour accéder à la propriété nom
de mon_chien, on utilise :
mon_chien.nom;
Cette notation se lit par la fin et signifie le nom
de mon_chien
.
Il est aussi possible de créer un objet en utilisant le format JSON :
var vehicule = { "marque": "BMW", "modele": "i3", "puissance": 170, "annee":2015 }; document.write(vehicule.constructor.name); console.log(vehicule);
L'objet vehicule
est dans ce cas un Object, objet de base du JavaScript :
Pour en savoir plus sur le format JSON, lisez cette fiche : Le format JSON : JavaScript Object Notation
Il est également possible d'associer à des objets, en plus de leurs propriétés, des fonctionnalités, codées sous forme de fonctions. Les fonctions associées à un objet sont appelées méthodes.
Il y a plusieurs façons de créer des méthodes sur un objet :
function CreerChien(le_nom, la_race) { this.nom=le_nom; this.race=la_race; this.afficher=afficherChien; }
Nous avons ici ajouté une méthode qui permet d'afficher les informations sur le chien :
function AfficherChien() { document.write("Ce chien s'appelle "+this.nom+". C'est un "+this.race+"."); }
On remarque encore l'utilisation de this qui représente l'objet sur lequel est appliquée la méthode.
Il est possible aussi de déclarer la fonction avec le mot with, qui évite d'avoir à répérer this.
devant chaque propriété :
function afficherChien() { with(this) { document.write("<p>Ce chien s'appelle "+nom+". C'est un "+race+".</p>"); } }
Créons quelques instances de CreerChien
:
var rantanplan = new CreerChien("Rantanplan", "batard à gros museau"); var milou = new CreerChien("Milou", "Fox Terrier"); rantanplan.afficher(); milou.afficher();
Le résultat de l'appel de cette méthode sur les instances milou et rantanplan est :
function CreerChien(le_nom, la_race) { this.nom=le_nom; this.race=la_race; this.afficher=AfficherChien; this.log = function() { console.log(this); }; } var pongo=new CreerChien("Pongo", "Dalmatien"); pongo.afficher(); pongo.log();
La méthode log()
est directement créée par une fonction sans nom, d'où le terme anonyme. Voir l'objet Function pour plus d'infos.
L'accès à la propriété prototype du constructeur autorise l'ajout de propriétés et de méthodes. Par exemple, ajoutons la propriété photo
et la méthode album()
au constructeur CreerChien
;
CreerChien.prototype.photo=""; CreerChien.prototype.album=function() { document.write("<img src='"+this.photo+"' width='160'/>"); } pongo.photo="pongo.gif"; pongo.album();
Les objets CreerChien
peuvent maintenant afficher leur photo :
Le format JSON permet de créer des objets avec des méthodes.
var vehicule2 = { "marque" : "Toyota", "modele" : "Aygo", "puissance" : 48, "annee" : 2012, "age" : function() { /* La méthode age retourne l'age à partir de l'année du véhicule */ var dt=new Date(); var age=dt.getFullYear()-this.annee; return age; } }; document.write("Ce véhicule a " + vehicule2.age() + " ans"); /* Détail du format de l'objet dans la console */ console.log(vehicule2.constructor.name); console.log(vehicule2);
L'instance vehicule2
possède des propriétés et la méthode age()
.
Le constructor est l'objet natif de base Object fabriqué par le format JSON.
L'héritage en programmation Objet est un concept essentiel qui facilite et organise le développement et évite la duplication inutile de code.
Pour bien comprendre l'héritage des objets, prenons l'exemple des objets du document HTML (le DOM = Document Object Model) :
<div id="monObjetDiv">div#monObjetDiv</div>
L'appel à getElementById() permet d'accéder à l'objet du document et de le manipuler (ici de l'afficher dans la console) :
var monObjetDiv=document.getElementById("monObjetDiv"); console.log(monObjetDiv);
Observez dans l'émulateur de la console la longue chaîne d'héritages de l'objet HTML div :
Voyons l'ensemble de l'héritage :
EventTarget
ajoute la possibilité de recevoir et traiter des événements EventNode
ajoute les propriétés de noeuds dans la hiérarchie du document HTML.Element
est la classe générale de base de tous les objets du document.HTMLDivElement
ajoute les propriétés spécifiques aux objets de tag div
. Tous les tags HTML ont une classe associée (HTMLBodyElement
, HTMLLinkElement
, HTMLSpanElement
, ... Le JavaScript a été assez long à profiter de la notion d'héritage, mais maintenant, tous les navigateurs le permettent.
Reprenon notre exemple d'animaux. Les objets de type Chien et Chat héritent des propriétés de Animal.
function Animal(nom, sexe, age, photo) { this.nom=nom; this.sexe=sexe; this.photo=photo; this.age=age; this.male="Mâle"; this.femelle="Femelle"; this.log=function() { var s = this.sexe=="F" ? this.femelle : this.male; console.log(s+" "+this.nom+" - "+s+" - "+this.age+" ans - "+this.photo); } this.display=function() { var s = this.sexe=="F" ? this.femelle : this.male; document.write("<div>"+s+" "+this.nom+"<br><img src='"+this.photo+"'></div>"); } } function Chien(nom, sexe, age, photo) { this.animal=Animal; this.animal(nom, sexe, age, photo); this.cri="Aboiement"; this.male="Chien", this.femelle="Chienne"; } function Cheval(nom, sexe, age, photo) { this.animal=Animal; this.animal(nom, sexe, age, photo); this.cri="Hennissement"; this.male="Cheval", this.femelle="Jument"; } var rantanplan=new Chien("Rantanplan", "M", 6, "rantanplan.png"); rantanplan.display(); rantanplan.log(); var rossinante=new Cheval("Rossinante", "F", 14, "rossinante.jpg"); rossinante.display(); rossinante.log();
Notez l'usage de l'opérateur ternaire pour définir le libellé mâle/femelle
L'opérateur JavaScript instanceof retourne true
si l'objet appartient à une des classes de la chaîne d'héritages :
var monObjetDiv=document.getElementById("monObjetDiv"); console.log(monObjetDiv instanceof HTMLDivElement); console.log(monObjetDiv instanceof HTMLElement); console.log(monObjetDiv instanceof Object);
Les 3 tests sont vrais :
Le JavaScript est extrêmement laxiste dans son implémentation. Il est même possible de modifier un objet natif JavaScript. C'est très pratique pour gérer les navigateurs anciens, exotiques ou non compatibles. Par exemple, on peut surcharger l'objet console si il n'existe pas, évitant ainsi des erreurs d'exécution. Dans la même idée, on peut ajouter des méthodes pour faciliter le développement et l'uniformisation du code.
window.console = window.console || { log: function() {return false} }