Javascript programmation objet




 

La notion de classe et d’objet étant utile dans le cadre du tutoriel sur le jeu Pong, je vous propose un bref rappel sur comment définir et utiliser vos propres objets en javascript. Il existe plusieurs manières de créer des objets en javascript, je vous montre celle qui semble la plus efficace.

La manière la plus évidente de définir un objet en javascript

1 – Définir une classe

Parce que proche des langages objets tels que java ou c#, il semble naturel de définir des objets par le biais d’une fonction qui encapsule :
– les propriétés;
– et les méthodes.

Exemple :

var Utilisateur = function(id, mdp) {
  this.identifiant = id;
  this.motdepasse = mdp;
  
  this.authentifier = function() {
    console.log("fonction authentifier définie dans l'objet");
    if ( this.identifiant == 'login' && this.motdepasse == 'password' ) {
      return true;
    }
    return false;
  }
}

Simple, non ?

Remarquez que :
– les propriétés sont préfixées par le mot clé this;
– qu’il n’y a ni accesseur (get), ni modificateur (set);
– la fonction Utilisateur prenant deux paramètres est considérée comme le constructeur.

Pour instancier une classe en objet, il suffit d’appeler l’opérateur new comme ceci :

 var utilisateur1 = new Utilisateur('id','mdp');
 utilisateur1.authentifier();
 var utilisateur2 = new Utilisateur('login','password');
 utilisateur2.authentifier();

Le premier appel renvoie false, et le deuxième appel renvoie true conformément à ce qui est attendu.

Rien à redire jusqu’ici puisque ça fonctionne.

2 – Problème de cette méthode

Comme les fonctions sont des variables pointant sur des fonctions anonymes, il est possible de redéfinir une fonction où vous voulez dans le code.

Illustration : ajoutez au code précédent la redéfinition de la méthode authentifier, puis rappelez la méthode authentifier sur les 2 objets utilisateur1 et utilisateur2 comme suit :

 var utilisateur1 = new Utilisateur('id','mdp');
 utilisateur1.authentifier();
 
 var utilisateur2 = new Utilisateur('login','password');
 utilisateur2.authentifier();
 
 utilisateur2.authentifier = function() {
  console.log("appel fonction authentifier définie à partir de utilisateur2");
  return false;
 }

 utilisateur1.authentifier();
 utilisateur2.authentifier();

A l’exécution, vous constatez à partir de la console (Chrome F12) que :
– l’appel utilisateur1.authentifier() est identique au premier appel : c’est toujours la fonction définie dans l’objet qui est exécutée;
– l’appel utilisateur2.authentifier() diffère du premier appel : c’est la fonction redéfinie qui est appelée.

Vous avez donc deux objets normalement identiques qui ont des comportements différents.
Ceci est du à la redéfinition de la méthode directement à partir de l’objet instancié utilisateur2.

Cependant, seule la méthode de l’objet instanciée est redéfinie.
La méthode de la classe elle ne change pas : si vous instanciez un nouvel objet, sa méthode authentifier sera identique à celle de la classe.

On constate donc que lorsqu’un objet est instancié, toutes ses variables et fonctions sont copiées dans l’objet résultant. Imaginez qu’avec une classe d’objet volumineuse, chaque instanciation d’objet aura le même volume que la classe elle-même. Une occupation de la mémoire inutile et non optimisée avec des effets de bord incontrôlés.

 

Une solution plus optimisée de définir un objet en javascript

Pour parfaire la solution précédente, il faudrait que toutes les instances d’une même classe partage la définition des méthodes. Les propriétés, quant à elles, ont par définition des valeurs différentes.

En javascript, les classes d’objet encapsulent toutes une structure de données appelées prototype.

La structure prototype est partagée par toutes les instances de cette classe. Du coup, tout ce qu’encapsule prototype est aussi partagé.

Il est donc préférable de passer par prototype pour définir les méthodes d’une classe comme ceci :

var Utilisateur = function(id, mdp) {
  this.identifiant = id;
  this.motdepasse = mdp;
}

Utilisateur.prototype.authentifier = function() {
   console.log("fonction authentifier définie dans l'objet");
   if ( this.identifiant == 'login' && this.motdepasse == 'password' ) {
     return true;
   }
   return false;
}

Cependant, ceci ne vous empêchera aucunement de redéfinir la méthode d’un objet instancié.

 

Conclusion

Les deux solutions proposées fonctionnent. Simplement, la seconde est plus optimisée dans la mesure où l’occupation mémoire est moindre.

 

Posté dans html5Taggé classe, HTML5, javascript, objet, pong  |  1 commentaire

Une réponse à "Javascript programmation objet"

Répondre

*