Vers la programmation orientée objet
Dans la programmation dite classique, les données sont passées à des fonctions, des procédures, qui se chargent de les traiter.
En programmation orientée objet, les données possèdent elles même des fonctions (on les appelle des méthodes)!
En programmation objet, on a la possibilité de garder une programmation procédurale.
1 L'objet en JavaScript
Le concept de base de la programmation orientée objet est bien évidemment l'objet, entité désignée également par le terme instance.
la notion d'objet est associé au concept de classe qui permet de définir la structure de l'objet, à savoir ses attributs et ses méthodes, ainsi que ses liens aux autres classes (héritage, association...). L'objet est alors créé à partir d'une classe par instanciation.
Tout d'abord, en JavaScript, la notion de classe n'existe pas et le langage n'est pas typé.
Le langage JavaScript permet de créer simplement un objet en se fondant sur l'objet Object ou en utilisant une forme litérale dont la syntaxe est décrite par la notation JSON.
var obj1 = new Object(); // A partir de l'objet Object
var obj2 = {}; // Avec la notation JSON
L’objet est considéré comme un tableau associatif
var obj = new Object(); obj["attribut"] = "valeur1";
// similaire à obj.attribut = "valeur1";
obj["methode"] = function(parametre1, parametre2) {
alert("parametres: " + parametre1 + ", " + parametre2);
};
// similaire à obj.methode = ...
// Affichage de la valeur de attribut de obj
alert("Valeur de attribut: " + obj.attribut);
// Exécution de la méthode methode de obj
obj.methode("valeur1", "valeur2");
Voici le même code en notation JSON.
var obj = {
attribut: "valeur",
methode: function(parametre1, parametre2) {
alert("parametres: " + parametre1 + ", " + parametre2);
}
}
// Affichage de la valeur de attribut de obj
alert("Valeur de attribut: " + obj.attribut);
// Exécution de la méthode methode de obj
obj.methode("valeur1", "valeur2");
2 Les indispensables pour la programmation objet
a La fonction
Une fonction peut être référencée par l'intermédiaire d'une variable et être utilisée telle quelle par la suite.
En JS, une fonction :
est considérée comme un objet de type "function".
rattachée à un objet est appelée "méthode"
possède une variable "arguments" dans tous les cas
peut avoir le même nom qu'une autre fonction déjà déclarée, auquel cas c’est la dernière déclarée qui sera exécutée
function test() {
alert("Nombre de paramètres: " + arguments.length);
for(var i=0; i < arguments.length; i++) {
alert("Paramètre " + i + ": " + arguments[i]);
}
}
test("valeur1", "valeur2");
b La closure
Une closure, c'est une fonction qui récupère les variables du scope où elle était.
function maFonction(parametre) {
var maVariable = parametre;
function monAutreFonction() {
alert("maVariable : " + maVariable);
}
return monAutreFonction;
}
var fonction = maFonction("mon paramètre");
fonction();// Affiche la valeur "mon paramètre"
Voici un exemple concret :
function incremente() {
var i = 0;
return function() {
return i++;
}
}
var g = incremente();
console.log(g()); // 0
console.log(g()); // 1
var h = incremente();
console.log(h()); // 0, not 2
c Le mot clé "this"
Il est utilisé dans une méthode afin de référencer l'instance sur laquelle est exécutée cette méthode.
var maFonction = function() {
alert("attribut: " + this.attribut);
};
maFonction();// Affiche la valeur undefined
var obj1 = {
attribut: "valeur1",
methode: maFonction
}
obj1.methode();// Affiche la valeur de attribut, à savoir valeur1
var obj2 = {
attribut: "valeur2",
methode: maFonction
}
obj2.methode();// Affiche la valeur de attribut, à savoir valeur2
3 Structure des objets avec JavaScript
a Structure simple
Le JS ne supporte pas le concept de "classe", nous allons utiliser les concepts des fonctions et closures du langage.
Le mot clé "new" permet d'initialiser un objet
Utilisation du mot clé "this" afin de définir les éléments publiques de la classe.
function maClasse(parametre1, parametre2) {
this.attribut1 = parametre1;
this.attribut2 = parametre2;
this.methode = function() {
alert("Attributs: " + this.attribut1 + ", " + this.attribut2);
}
}
var obj = new maClasse("valeur1", "valeur2");
alert("Attribut1: " + obj.attribut1); // Affiche la valeur de l'attribut attribut1
obj.methode(); // Affiche la chaîne de caractères contenant les valeurs des attributs
En remplacant "this" par "var" les éléments deviennent privés
function maClasse(parametre1, parametre2) {
var attribut1 = parametre1;
var attribut2 = parametre2;
this.methode = function() {
alert("Attributs: " + this.attribut1 + ", " + this.attribut2);
}
}
var obj = new maClasse("valeur1", "valeur2");
alert("Attribut1: " + obj.attribut1); // retourne undefined
obj.methode(); // Affiche la chaîne de caractères contenant les valeurs des attributs
On peut en faire de même pour rendre une méthode privée. Attention on ne pourra plus faire appel à la méthode en dehors de la fonction.
function maClasse(parametre1, parametre2) {
var attribut1 = parametre1;
var attribut2 = parametre2;
var methode = function() {
alert("Attributs: " + this.attribut1 + ", " + this.attribut2);
}
}
var obj = new maClasse("valeur1", "valeur2");
alert("Attribut1: " + obj.attribut1); // retourne undefined
obj.methode(); // retourne une erreur : obj.method is not a function
La déclaration des classes de cette manière reste simple mais suppose un problème de performance.
En effet, à chaque appel de la méthode de construction de l'objet, une nouvelle méthode "methode" est créée pour l'objet.
Pour améliorer la performance, il faudrait que tous les objets de type "maClasse" pointent vers une seule est unique méthode "methode" commune à tous ces objets.
La fonctionnalité de prototypage de JavaScript permet de pallier à cet aspect.
b Le prototypage
le prototypage correspond à spécifier une sorte de modèle indépendamment du constructeur afin d'initialiser chaque objet à sa création.
Pour se faire, on utilise la propriété "prototype" de l’objet "function"
function maClasse(parametre1, parametre2) {
this.attribut1 = parametre1;
this.attribut2 = parametre2;
}
maClasse.prototype = {
methode: function() {
alert("Attributs: " + this.attribut1 + ", " + this.attribut2);
}
}
var obj = new maClasse("valeur1", "valeur2");
alert("Attribut1: " + obj.attribut1); // Affiche la valeur de l'attribut attribut1
obj.methode(); // Affiche la chaîne de caractères contenant les valeurs des attributs
Comme vous avez pu le voir, JavaScript met en oeuvre une variante de la programmation orientée objet, à savoir la programmation orientée objet par prototype.