Accueil

Traduction

Tutoriel sur Javascript

Recherche dans ce tuto

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

JS & POO : créer ses propres objets

Dans le chapitre précédent j'ai évoqué les modèles prédéfinis d'objets et leurs méthodes : Date, String, Math, Array, Set, Map, RegExp, etc.

Dans ce chapitre je vous montre comment créer vos propres modèles d'objets puis des instances de ces modèles.
La POO en JavaScript présentait plusieurs particularités qui la distinguait des langages classiques comme Java ou C++.
Mais progressivement JS se rapproche des autres langages en matière de POO. Ainsi le concept de classe a été introduit par la version majeure de 2015.

Donc il existe différentes solutions pour créer vos propres objets sous JavaScript.

Création d'objets par un constructeur

Un constructeur est simplement une fonction définissant un modèle d'objet avec des propriétés et des méthodes.

Exemple 1 : le modèle d'objet ne comprend que des propriétés

C'est le cas le plus simple.

Le script

La fonction f1() est appelée par un élement BUTTON.

Le modèle d'objet créé se nomme "voiture" et comprend quatre propriétés.
Je crée ensuite deux instances du modèle "voiture" : auto_jean & auto_paul.
Notez la syntaxe pour créer des objets (instances) du modèle "voiture : let nomObjet = new NomModèle(propriétés)
On peut donc dire qu'un objet est une séquence de paires propriété:valeur.
Notez l'emploi de la notation pointée : objet.propriété pour afficher la valeur d'une propriété.
Dans l'avant dernière instruction du script j'utilise la notation template strings pour éviter une concaténation fastidieuse de l'instruction précédente.

Le rendu dans un Iframe de ce document

À la question quel est le type de donnée ; la réponse est "object".

Exemple 2 : le modèle d'objet propose propriétés et méthodes

Rappel : une méthode est en fait une fonction spécifique au modèle d'objet.

Le code du document HTML

Un bouton de commande appelle la fonction f1().
Le script :

Le modèle d'objet créé se nomme voiture et comprend 4 propriétés et une méthode.
La méthode se nomme presenter() qui affiche ici toutes les propriétés de l'objet concerné.
Pour décrire une méthode il faut employer les mots réservés function et return.
Pour appeler une méthode il faut employer la syntaxe : objet.methode() ; n'oubliez pas les parenthèses, une méthode c'est une fonction !

Je procède ensuite à un changement de propriétés pour l'instance "mavoiture".
Notez la syntaxe pour modifier la valeur d'une propriété : objet.propriété ="nouvelle valeur".
On dit que l'on utilise la notation pointée.

Je peux accéder directement aux propriétés de l'objet pour les modifier. On dit que ces propriétés sont publiques.
Plus loin dans ce chapitre je vous montre comment rendre les propriétés privées.

Le rendu dans un Iframe de ce document

À la question quel est le type de donnée ; la réponse est "object" et non pas "voiture" ...

Les classes et l'héritage - notation pointée optionnelle

En POO classique, une modèle d'objet est appelé classe.
La classe définit donc les propriétés et les méthodes applicables aux instances de cette classe.

Pour se rapprocher de la syntaxe POO des autres langages, la version ECMAScript de 2015 introduit les mots clé "class", & "extends" (pour l'héritage).

Dans l'exemple qui suit je définit une classe ; puis je crée une deuxième classe héritant de la première ; je crée ensuite des instances de la classe mère et des instances la classe fille.
J'évoque aussi dans ce paragraphe la notation pointée optionnelle.

Le code du document HTML

Le script :

Étude détaillée de ce script

Définition de la classe mère

Je définis donc la classe "Auto" ; il est d'usage que la première lettre de la classe soit une majuscule.
La méthode constructor() initialise les propriétés.
Notez que la classe "Auto" ne comprend que des propriétés.

Définition de la classe fille

À partir de la classe "Auto" je définis la classe "Tacot" par héritage avec l'instruction class Tacot extends Auto.
On retrouve la méthode constructor() pour initialiser les propriétés (au nombre de 6).
La méthode super() initialise les propriétés de la classe parente.
Je définis ensuite deux nouvelles propriétés (annee & etat) et une méthode nommée "presenter()".

Créer des instances (ou objets)

Ayant défini la classe "Auto" et la classe "Tacot" je peux créer des instances de ces différentes classes.

Le rendu du document dans un Iframe

Encapsulation

Définition

Pour prévenir de tentatives d'injections (de HTML ou JS), les propriétés d'un objet doivent être privées c'est à dire qu'elles ne sont pas accessibles directement ; Pour modifier ces propriétés il faut passer par une méthode, qui elle est publique. C'est le principe de l'encapsulation.

JS n’a pas de modificateurs d’accès natifs (private, public, protected) comme d’autres langages. Cependant, il existe plusieurs méthodes pour produire l’encapsulation.

Le code du document HTML

Dans cet exemple, nous avons créé une classe BanqueCompte à l’aide du mot-clé class. Cette classe définit trois propriétés privées : _num, _nom et _solde.
Ces propriété sont précédées d’un trait de soulignement pour les rendre privées.
Notez les sécurités prévues dans la fonction constructor() pour neutraliser les tentatives d'injections de code et les saisies maladroites.

	this._num = num.trim(); // supprimer espace
    this._nom = nom.replaceAll('<','').replaceAll('>','').trim(); 
	// rendre inoffensive une injection HTML
    this._solde = parseInt(solde); // convertir la chaine en entier


Je crée une instance de cette classe nommée "monCompte" via la fonction constructor() ; je saisis des chaines avec des caractères non autorisés (parenthèses angulaires, espaces) ; heureusement le constructeur corrige.

On ne peut modifier les propriétés d'un objet qu'au travers de la méthode publique deposer()
Si vous tentez d'accéder directement à une propriété privée de l'objet, l'instruction n'est pas prise en compte. Mais le script ne 'plante' pas ; c'est transparent. Ainsi le solde ne change pas (reste à 1500 suite au dépôt de 500).

Le rendu de l'exemple

Trois instructions qui tentent de modifier les valeurs des trois attributs n'ont pas été exécutées.

Remarque

Depuis ES2022, JavaScript supporte les champs privés avec le préfixe #.

Le polymorphisme

Définition du concept

Le polymorphisme en POO permet à des objets de classes différentes de répondre différemment à la même méthode, prolongeant ainsi les capacités de l'héritage et optimisant la réutilisation du code.

Exemple - le code

Les classes Singe & Humain héritent de la classe Primate.

Dans chaque classe une méthode nommée "communiquer()".
Cette méthode n'aura pas le même retour selon le type de l'objet auquel on l'applique.
Emploi de la méthode forEach() pour parcourir un tableau indicé.
La propriété constructor.name indique de façon très précise le type d'objet ; voir plus loin dans ce chapitre.

Le rendu

Création d'un objet JS de façon littérale

Cette technique permet de créer rapidement un objet isolé ou une liste d'objets ayant des structures simples.

Syntaxes

Pour créer un objet avec seulement des propriétés :
nomObjet = {propriété : "valeur", propriété : "valeur" , ... , propriété:valeur}
La description de l'objet est encadrée par des accolades.

Pour créer un objet avec propriétés et méthode :
nomObjet = {propriété : "valeur", propriété : "valeur" , ... , nomMéthode: function(){liste instructions} }
N'oubliez pas le mot clé function pour décrire la méthode.

Remarque

La création d'un objet JS de façon littérale s'effectue en utilisant une syntaxe très proche du format JSON.
Vous verrez plus loin qu'il est possible de convertir un objet JS en chaine au format JSON et vice-versa.

Création d'objet JS de façon littérale - exemple 1

Le script

Ci-dessous je crée un objet JS avec trois propriétés et une méthode.

    L'objet est affiché de trois façons :
  1. appel de la méthode presenter() appliquée à l'objet
  2. appel de la méthode JSON.stringify() appliquée à l'objet
  3. document.write(nomObjet)

Le rendu

Création d'objet JS de façon littérale - exemple 2

Dans un script je crée de façon littérale un objet nommé "bar" (le poisson) avec des propriétés et une méthode.
Pour certaines propriétés il peut y avoir plusieurs valeurs.
La méthode "fiche" génère du code HTML.

Le script

L'objet bar décrit ce poisson osseux à la chaire succulente.
L'objet comprend 5 propriétés et une méthode fiche().
Attention la propriété "vernaculaires" (vernaculaire ou commun) a deux valeurs d'où l'emploi des crochets pour indiquer que la valeur est un "array".

La méthode "fiche" génère du code HTML pour afficher toutes les propriétés y compris l'image.

Comme dans l'exemple précédent, j'affiche le détail de l'objet JS avec la méthode JSON.stringify().

Observez très attentivement les trois dernières instructions du script :

Le rendu du document

Affichez la console !

Les conversions

Dans le paragraphe précédent j'ai évoqué la méthode JSON.stringify(objetJS) mais sans donner beaucoup d'explications.

Les différentes méthodes

La méthode JSON.stringify()

Cette méthode convertit un objet en une chaine au format JSON. Après cette conversion on peut afficher l'objet telle une chaine.

La méthode JSON.parse()

Cette méthode convertit une chaine au format JSON en un objet.

Après cette conversion on peut appliquer la notation pointée pour accéder aux différentes propriétés de l'objet.

Exemple

Le script

Le rendu

Connaitre le type précis d'un objet

Problèmatique

Il peut être utile de connaitre de façon précise le type d'un objet.
Ainsi vous saurez quelles méthodes et propriétés lui appliquer.

Pour connaitre le type d'un objet vous pensez naturellement à l'opérateur typeof mais il y a beaucoup mieux ...

Typeof n'est guère précis. Ainsi pour une chaine il peut retourner "string" ou "objet" selon que la chaine a été créée avec le constructeur String ou de façon littérale.
Appliqué à une date, un array, un set, un objet JSON il retourne "object" ...
La propriété constructor.name appliquée est beaucoup plus précise comme je le montre dans l'exemple ci-dessous.

Exemple - script

Déroulez !

Je rappelle ensuite trois techniques pour créer des objets perso : construteur, classe, de façon littérale.

Ensuite pour chacun de ces objets je demande le type via l'opérateur typeof puis via la propriété constructor.name.

Le rendu

Notez que la propriété constructor.name retourne "Object" uniquement lorsqu'il s'agit d'un objet perso produit de façon littérale.

Liste d'objets simples

Il est facile de créer un tableau indicé d'objets ; tous les objets ayant la même structure.

Le script

Membres est un tableau indicé d'objets JS.

Le rendu du document

Remarque

Plutôt que créer un tableau indicé d'objets, il est préférable d'utiliser un tableau de clés-valeurs (un map).
L'accès par clé à un élément est alors possible.
Les séries de valeurs : array,map,set