Introduction

Puisque Javascript n'est pas un langage à proprement parlé Objet, puisque c'est un Langage Orienté Prototype (LOP), le concept d'objet peut être confus. Néanmoins, le fait qu'il s'agit de construire des prototypes, la modification des objets peut être fait d'une manière très avancée. En fait, on peut construire et déconstruire à peu près tous les objets et les prototypes pour les cuisiner à notre goût.

Construction

Un prototype/objet est construit à l'aide d'une fonction de base. La fonction fait référence à elle même, à l'aide de la variable "this". Le nom de la fonction deviendra le nom de l'objet. Pour avoir un objet Cube, on crée la fonction Cube().

function Cube() { }

À cette fonction, on peut attribuer des attributs internes.

function Cube ( taille ) {
 this.taille = taille;
 this.couleur = 'rouge';
}

Comme vous pouvez le voir, le mot-clé "this" représente la fonction, objet ou prototype en lui-même.

Initialisation

Avec fonction-constructeur et l'opérateur new

On peut initialiser un objet de plusieurs manières, soit appeler une fonction d'initialisation:

var maVariableDuCube1 = new Cube ( 5 ) ;

Cette manière de procéder permet d'exécuter la fonction Cube(taille). Cette fonction devient son constructeur. On pourra ensuite accéder à l'objet à l'aide de la variable "maVariableDuCube1" et accéder aux attributs à l'aide du caractère point: maVariableDuCube.taille, maVariableDuCube.couleur, etc.

Sans opérateur new

La deuxième façon de créer un objet, est de tout construire à l'aide de la syntaxe avec accolades.

var maVariableDuCube2 = {taille: 5, couleur: 'rouge' }; 

Il s'agit quand même d'un objet à proprement parler en javascript. Il n'y a pas de méthode qui joue le rôle de constructeur. Il faut donc toujours retaper les attributs pour chacune des instances. Chaque attributs ou méthodes doivent être séparés par des virgules, et l'accolade de fin doit être suivit d'un point-virgule.

Pour vous convaincre qu'il s'agit bel et bien de deux objets, vous pouvez les tester en affichant le type de la variable.

alert( "Var1: " + typeof(maVariableDuCube1) + ", Var2: " + typeof(maVariableDuCube2) );

Ce qui devrait afficher: Var1: object, Var2: object

On peut pousser cette syntaxe beaucoup plus loin:

var maVariable = {
 taille: 5,
 couleur: 'rouge',
 getTaille: function() { return this.taille; },
 getCarre : function() { return this.taille * this.taille; }
}

Avec constructeur contracté

var maVariableDuCube3 = new function Cube() {this.n=5; this.couleur='rouge';}; 
alert(typeof(maVariableDuCube3));
var var3 = new Cube();
var var4 = new Cube();

On a encore, le type 'object'. Même s'il y a une affection de la fonction Cube, l'opérateur 'new' spécifie qu'il s'agit de la création d'un nouvel objet. On peut alors réutiliser la fonction Cube pour d'autre objet. Un des inconvénients de cette méthode contractée est qu'il n'existe pas de moyen d'envoyer des paramètres à la fonction (pas d'après ce que j'ai essayé).

Méthode

Ajouter des méthodes à nos objets

function monAlerte( ) { alert('S.O.S.'); }
function monAjout(a , b) { return a+b; }
function AutreNomDeFonction() { return this.attribut1; }

function monObjet( ) {
 this.attribut1 = 10;
 this.monAlerte = monAlerte;
 this.monAjout = monAjout;
 this.getAttribut = AutreNomDeFonction;
}

// appel
var uneInstance = new monObjet();
uneInstance.monAlerte();
alert( uneInstance.monAjout(4,5) );
alert( uneInstance.getAttribut() );

Toutes ces initialisations vont fonctionner. On peut aussi initialiser la fonction à l'intérieur du constructeur.

function monObjet() {
 this.maFonction = function(a) { alert(a); }
}
var uneInstance = new monObjet();
uneInstance.maFonction('Allo');

Remarquer qu'il s'agit d'une affectation de la nouvelle fonction et qu'il n'y a pas de nom de fonction avant les paramètres.

Ajouter ou redéfinir des méthodes:

On peut ajouter ou redéfinir des méthodes déjà présentes. Par exemple, chaque Object possède la fonction toString() par défaut. On peut la modifier en utilisant les prototypes.

function afficheMonObjet() {
 alert( "VarA: " + this.a + ", VarB: " + this.b ) ;
}
function monObjet() {
 this.a = 'a';
 this.b = 'b';
}

// ajout ou redéfinition à la définition de l'objet
monObjet.prototype.toString = afficheMonObjet; // redéfinition de la méthode toString existante
monObjet.prototype.affiche  = afficheMonObjet; // ajout de la fonction affiche

De la même manière, on peut ajouter des méthodes pour tous les objets/prototypes existants. En javascript, on peut même le faire avec les objets du DOM (HTML, XML, ...). Voici quelques exemples:

Date.prototype.formatFrancais = function() { 
 return this.getFullYear() +"/" + (this.getMonth()+1) + "/" + this.getDate();
}
var d = new Date();  
alert( d.formatFrancais );


String.prototype.cap = function() { 
 return this.charAt(0).toUpperCase() + this.substring(1,this.length); 
}
alert( "allo".cap() );


Number.prototype.carre = function() { return this.valueOf() * this.valueOf(); }; 
// oui, il faut un espace entre le nombre et le point, 
// sinon c'est un nombre avec décimal.
alert( 10 .carre() ); // affiche 100
var x = 5.2;
alert( x.carre() );


HTMLParagraphElement.prototype.getClassAndTitle = function() { 
 return this.className + ' : ' + this.title; 
}
var monP = document.createElement("P");
monP.className = 'allo';
monP.title = 'mon titre';
alert( monP.getClassAndTitle() ); // affiche 'allo : mon titre'

Attribut

function monObjet(param1) {
  this.attribut1 = param1;
  this.attribut2 = 5;
  this.attribut3 = 'chaine';
}
// ajout d'attribut à la définition de l'objet
monObjet.prototype.attribut5 = 'Nouveau';

var uneInstance = new monObjet(1);
alert( uneInstance.attribut1 + ":" + uneInstance.attribut5); // affiche 1:Nouveau

Note

Puisqu'un objet peut contenir des objets la syntaxe suivante est valide:

// maFonction est une fonction de l'objet "sousObjetInterne"
// sousObjetInterne est un objet de "objetInterne"
// objetInterne est un objet de "monObjet"
monObjet.objetInterne.sousObjetInterne.maFonction();

De plus, si une fonction retourne un tableau ou un objet, on peut l'utiliser immédiatement:

/* retourne un tableau, 
   puis exécute une fonction sur le quatrième élément et 
   obtient la valeur d'un attribut : façon longue */
var tableau = monObjet.getTableau();
var element = tableau[3];
var objet = element.getObjet();
var valeur = objet.value

/* même chose : façon courte */
var valeur = monObjet.getTableau()[3].getObjet().value;

Référence...