Auteur: Ludovic PATEY

Publié le 14 février 2008

Modifié le: 15 février 2008

Page d'accueil

Les objets

Vous êtes ici : Accueil / Cours / Cours de Javascript / Débuter en Javascript

Bien que Javascript ne soit pas un langage orienté objet, presque toutes ses manipulations se font sur des objets : la page est un objet, toute balise html est un objet, les tableaux et les fonctions en sont également...

Qu’est-ce qu’un objet ?

Un objet est un ensemble de propriétés et méthodes formant un tout logique. Par exemple, une voiture a pour propriétés sa couleur, ses dimensions, sa vitesse maximum ... et pour méthodes les actions "rouler", "tourner", "faire le plein" ...

Quelques définitions

Une classe est la définition de l’ensemble des propriétés et méthodes de l’objet.

Une propriété et une methode sont respectivement une variable et une fonction associées à un objet.

Une instanciation est la création d’un objet à partir de sa classe.

Syntaxe d’utilisation des objets

Pour accéder à une propriété ou une méthode d’un objet, il suffit d’interposer un point entre les 2 :

monObjet.maPropriete = ma_valeur;

monObjet.maMethode( param1, param2 ... );

Exemple :

maVoiture.couleur = 'rouge';

// Tourne à 45 degrés
maVoiture.tourner( 45 );

Définition des objets

Avant d’utiliser un objet, il est nécessaire de l’avoir instancié à partir de sa classe qui définit ses propriétés et méthodes.

Attention ! Bien que le mot-clé function soit le même, il existe une grande différence entre une fonction et une classe. Le code suivant va utiliser function pour définir une classe.

function Voiture() {

       this.couleur = 'bleu';

       this.tourner = function( degres ) {
               // Code pour tourner
       }

}


var maVoiture = new Voiture();

Comme vous le voyez, une méthode n’est au fait rien d’autre qu’une fonction stockée dans une propriété. En effet, une fonction est un objet, or une propriété peu contenir un objet.

Nous introduisons ici un nouvel opérateur : new. Attention, si cet opérateur est omis, il ne s’agira plus d’une instanciation, mais d’une simple exécution de fonction. maVoiture ne contiendrait donc pas un objet mais le retour de la fonction Voiture()

Le pointeur this

La variable this est définie à l’intérieur d’un objet. Il pointe vers l’objet courant. Par exemple, le code suivant va afficher ’bleu’ :

function Voiture() {

       this.couleur = 'bleu';

       this.afficherCouleur = function() {

               // Afficher la couleur de son propre objet
               alert( this.couleur );
       }

}


var maVoiture = new Voiture();

maVoiture.afficherCouleur();

Le constructeur

Le constructeur est en programmation orientée objet une méthode qui est appelée lors de l’instanciation. En javascript, il est remplacé par le code se trouvant entre les accolades de la définition de la classe :

function Voiture() {

       // Equivalent du constructeur
       // S'execute lors de l'instanciation
       alert( 'ok' );

}


// Va afficher 'ok'
var maVoiture = new Voiture();

Les prototypes

La définition de propriétés et méthodes que nous avons définies au niveau du constructeur sont des propriétés et méthodes d’instance, c’est à dire qu’elles sont différentes pour chaque objet : Le code suivant va afficher false

function Voiture() {

       this.tourner = function( degres ) {
               // Code pour tourner
       }
}

var v1 = new Voiture();
var v2 = new Voiture();

alert( v1.tourner == v2.tourner );

Ce qui prouve que la méthode tourner de chaque objet est différente. A chaque instanciation, une nouvelle méthode est créée.

Le code précédent est l’équivalent du code suivant :

function Voiture() {
}

var v1 = new Voiture();
var v2 = new Voiture();

v1.tourner = function( degres ) {
       // Code pour tourner
}

v2.tourner = function( degres ) {
       // Code pour tourner
}


alert( v1.tourner == v2.tourner );

Nous voyons tout de suite que le corps de la méthode tourner() ne dépend pas de l’instance. Il est donc inutile de la recréer pour chaque instance. Il est possible de créer des propriétés et méthodes de classe. Celles-ci sont partagées par toutes les instances de la classe, entraînant un gain parfois énorme d’espace mémoire.

La création de propriétés et méthodes de classe se fait à l’aide des prototypes :

Un prototype est un objet partagé par toutes les instances d’une classe, et dont les propriétés et méthodes seront appelées si elles ne sont pas trouvées dans l’instance de la classe.

Voici la syntaxe utilisée :

function MaClasse() {
}


// Definition d'une propriété de classe
MaClasse.prototype.maPropriete = ma_valeur;

// Définition d'une méthode de classe
MaClasse.prototype.maMethode = function() {
       // Corps de ma fontion
}

Revenons au cas de la voiture. Le code suivant affichera désormais true :

function Voiture() {
}

Voiture.prototype.tourner = function( degres ) {
       // Code pour tourner
}

var v1 = new Voiture();
var v2 = new Voiture();

alert( v1.tourner == v2.tourner );

Comme vous le voyez, la définition de propriétés et méthodes de classe ne sont rien d’autre que des propriétés et méthodes d’instance pour l’objet prototype.

Le prototype est une sorte de substitut à la notion d’héritage en programmation orientée objet.

Créer des propriétés et méthodes privées

Il est parfois utile de créer des propriétés et méthodes qui ne seront pas accessibles en dehors de l’objet. Il faut pour cela les déclarer dans le constructeur et remplacer le this par un var :

function Voiture() {

       // Definition d'une methode privée
       var userLesPneus = function() {
               alert( "Les pneus s'usent" );
       }

       this.rouler = function() {

               userLesPneus();
       }

}

var maVoiture = new Voiture();

// Retourne un message d'erreur
maVoiture.userLesPneus();

// Affiche "Les pneus s'usent"
maVoiture.rouler();

L’opérateur instanceof

Les objets n’ont pas les mêmes propriétés et méthodes en fonction de leur classe. Comme Javascript est un langage faiblement typé, il peut arriver que nous nous retrouvions avec un objet dont nous ignorons le type.

Il est possible de savoir si un objet appartient à une classe grâce à l’opérateur instanceof :

var maVoiture = new Voiture();

// Va afficher true
alert( maVoiture instanceof Voiture );

Le mot-clé with

Lorsque nous avons beaucoup d’appels de méthodes d’un même objet en même temps, la syntaxe identificateurObjet.identificateurMethode() peut s’avérer lourde. Le mot-clé permet de rendre implicite l’identificateur de l’objet :

with( maVoiture ) {

       // Equivalent de maVoiture.rouler();
       rouler();
}

Les références

Lorsque nous affectons un objet à une variable, nous ne copions pas vraiment la donnée, mais une référence à l’objet stocké en mémoire. Il s’agit tout simplement de l’adresse vers l’emplacement mémoire de l’objet. Cette notion est à prendre en compte dans le code suivant :

function Voiture() {

}

var v1 = new Voiture();
var v2 = v1;

v1.couleur = 'bleu';

// Affiche 'bleu'
alert( v2.couleur );

Une fonction étant un objet, les références expliquent que même si 2 fonctions ont le même corps, le code suivant affichera false :

var fonction1 = function() {
       alert( 'ok' );
}

var fonction2 = function() {
       alert( 'ok' );
}

// Affiche 'false'
alert( fonction1 = fonction2 );

La réflexivité des objets

La réflexivité d’un langage est sa capacité à se manipuler par son propre code. Javascript gère quelques notions de réflexivité.

Il est possible d’appeler une propriété ou une méthode avec la syntaxe suivante :

monObjet['maPropriete'] = ma_valeur;

monObjet['maMethode']( param1, param2 ... );

Cette nouvelle syntaxe va permettre d’accéder dynamiquement à des propriétés ou des méthodes. Prenons l’exemple du code suivant :

var methode = 'tourner';

var maVoiture = new Voiture();

// Equivalent à maVoiture.tourner( 45 );
maVoiture[ ma_methode ]( 45 );

Les méthodes call() et apply()

Nous avons vu comment accéder à des propriétés et méthodes de manière dynamque grâce à la réflexivité du langage.

Il reste cependant à voir comment invoquer des méthodes de manière dynamique. Ceci est rendu possible grâce aux méthodes call() et apply() de l’objet Function

Un article a été écrit à leur sujet :

Quelques fonctions intéressantes de Javascript

Voici quelques fonctions javascript qui gagnent à être connues, de par leur puissance et leur flexibilité.

Lister les propriétés et méthodes

Il existe une syntaxe permettant de lister les propriétés et méthodes d’un objet : le for..in. Il s’agit d’une syntaxe dérivée de la manipulation des tableaux. Sa syntaxe sera explicitée lors de l’étude des tableaux.

function Voiture() {

       this.couleur = 'bleu';

       this.tourner = function( degres ) {
               // Code pour tourner
       }

}

var maVoiture = new Voiture();

for( var prop in maVoiture ) {

       alert( prop );
}

La combinaison de la réflexivité et de l’opérateur instanceof va permettre de différencier les propriétés des méthodes :

// Pour chaque identificateur de propriété ou de méthode
for( var prop in maVoiture ) {

       // Si la valeur correspondante est une instance de fonction
       if( maVoiture[ prop ] instanceof Function ) {
               alert( prop + ' est une méthode' );
       }
       else {
               alert( prop + ' est une propriété' );
       }
}

Commentaires

Auteur :

Message :