[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/class [Back]  [Original]

Syntaxe de base de la Classe
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Syntaxe de base de la Classe

    En langage orient objet, une classe est un modle de code programme extensible servant crer des objets. Elle fournit les valeurs initiales de ltat (les variables membres) et de limplmentation du comportement (les fonctions ou mthodes membres).

    Wikipedia

    En pratique, nous avons souvent besoin de crer beaucoup dobjets de mme type, tels que des utilisateurs, des biens ou toute autre chose.

    Comme nous le savons dans le chapitre Le constructeur, l'oprateur "new", new function peut nous aider faire cela.

    Mais dans le JavaScript moderne, il y a une construction de la classe plus avance qui introduit de nombreux nouveaux aspects utiles en langage orient objet.

    La syntaxe de classe

    La syntaxe de base est :

    class MyClass {
      // Les mthodes de la classe
      constructor() { ... }
      method1() { ... }
      method2() { ... }
      method3() { ... }
      ...
    }

    Vous pouvez ensuite utiliser new MyClass() pour crer un nouvel objet ayant toute la liste des mthodes.

    La mthode constructor() est automatiquement appele par new, donc nous pouvons initialiser lobjet ce niveau.

    Par exemple :

    class User {
    
      constructor(name) {
        this.name = name;
      }
    
      sayHi() {
        alert(this.name);
      }
    
    }
    
    // Usage:
    let user = new User("John");
    user.sayHi();

    Lorsque new User("John") est appel :

    1. Un nouvel objet est cr.
    2. Le constructor sexcute avec les arguments qui lui sont passs et assigne this.name a lobjet.

    ensuite nous pouvons appeler les mthodes de lobjet, tel que user.sayHi().

    Pas de virgule entre les mthodes de la classe

    Un pige frquent des dveloppeurs novices est de mettre une virgule entre les mthodes de la classe, entrainant ainsi une erreur syntaxique.

    La notation ici ne doit pas tre confondue avec les objets littraux. A lintrieure dune classe, aucune virgule nest requise.

    Quest-ce quune classe ?

    Alors, cest quoi exactement une class ? Ce nest pas totalement une nouvelle entit au niveau du langage, comme on pourrait le penser.

    Dvoilons maintenant la magie et regardons ce quest rellement une classe. Cela va nous aider comprendre plusieurs aspects complexes.

    En JavaScript, une classe est une sorte de fonction.

    Regardons ici :

    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // La preuve : User est une fonction
    alert(typeof User); // function

    Ce que la construction de la classe classe User {...} fait rellement, cest :

    1. Crer une fonction nomme User, qui devient le rsultat de la dclaration de la classe. Le code de la fonction est tire de la mthode constructor (considre comme tant vide au cas ou cette mthode nest pas crite).
    2. Garde les mthodes de la classe, telle que sayHi, dans User.prototype.

    Aprs la cration de new User, lorsque nous appelons sa mthode, elle est extraite du prototype, comme dcrit dans le chapitre F.prototype. Donc, lobjet a accs aux mthodes de classe.

    Nous pouvons illustrer le rsultat de la dclaration de class User ainsi :

    []

    Voici le code pour une introspection :

    class User {
      constructor(name) { this.name = name; }
      sayHi() { alert(this.name); }
    }
    
    // classe est une fonction
    alert(typeof User); // function
    
    // ...ou, plus prcisment, le constructeur de la mthode
    alert(User === User.prototype.constructor); // true
    
    // Les mthodes sont dans User.prototype, par exemple :
    alert(User.prototype.sayHi); // le code de la mthode sayHi
    
    // Il y a exactement deux mthodes dans le prototype
    alert(Object.getOwnPropertyNames(User.prototype)); // constructeur, sayHi

    Pas simplement un sucre syntaxique

    Parfois certaines personnes disent que la notion de class est un sucre syntaxique (une syntaxe qui est destine rendre la lecture plus facile, mais elle nintroduit rien de nouveau), parce quen ralit nous pouvons dclarer la mme chose sans utiliser le mot cl class :

    // Rcriture de class User en fonctions pures
    
    // 1. Crer la fonction constructeur
    function User(name) {
      this.name = name;
    }
    // un prototype de fonction a une proprit constructeur par dfaut,
    // nous n'avons donc pas besoin de le crer
    
    // 2. Ajouter la mthode au prototype
    User.prototype.sayHi = function() {
      alert(this.name);
    };
    
    // Usage:
    let user = new User("John");
    user.sayHi();

    Le rsultat de cette dfinition est peu prs la mme chose. Donc, il y a bien des raisons de vouloir considrer class comme pouvant tre un sucre syntaxique pour dfinir un constructeur ensemble avec ses mthodes de prototype.

    Cependant, il existe des diffrences importantes.

    1. Premirement, une fonction cre par class est labellise par une proprit interne spciale [[IsClassConstructor]]: true. Ce nest donc pas tout fait la mme chose que de le crer manuellement.

      Le langage vrifie cette proprit divers endroits. Par exemple, contrairement une fonction rgulire, elle doit tre appele avec new :

      class User {
        constructor() {}
      }
      
      alert(typeof User); // fonction
      User(); // Erreur: le constructeur Class User ne peut tre invoque sans 'new'

      Aussi, la reprsentation en chane de caractres dun constructeur de class dans la plupart des moteurs de JavaScript commence avec class :

      class User {
        constructor() {}
      }
      
      alert(User); // class User { ... }

      Il y a dautres diffrences, nous les verrons bientt.

    2. Les mthodes de Class sont non-numrable. Une dfinition de la classe attribue false la proprit enumerable pour toutes les mthodes du "prototype".

      Cest bien, parce que si nous excutons un for..in sur un Object, souvent nous ne voulons pas accder aux mthodes de sa classe.

    3. Les Classes utilisent toujours use strict. Tout code lintrieur de la construction de la classe est automatiquement en mode strict.

    En outres, la syntaxe classe apporte beaucoup dautres caractristiques que nous allons explorer plus tard.

    LExpression Class

    Tout comme les fonctions, les classes peuvent tre dfinies a lintrieur dune autre expression, passes en paramtres, retournes, assignes etc.

    Voici un exemple dexpression dune classe :

    let User = class {
      sayHi() {
        alert("Hello");
      }
    };

    Similairement aux Fonction Expressions nommes, les expressions de classe peuvent avoir un nom.

    Si une expression de classe a un nom, il est visible lintrieur de la classe uniquement :

    // "Expression de Classe nomme"
    // (Terme non existant dans la spcification, mais elle est similaire a une Expression de Fonction nomme)
    let User = class MyClass {
      sayHi() {
        alert(MyClass); // le nom MyClass est seulement visible dans la classe
      }
    };
    
    new User().sayHi(); // a fonctionne, montre la dfinition de MyClass
    
    alert(MyClass); // erreur, le nom MyClass n'est pas visible en dehors de la classe

    Nous pouvons mme crer les classes dynamiquement la demande, comme suit :

    function makeClass(phrase) {
      // dclare une classe et la retourne
      return class {
        sayHi() {
          alert(phrase);
        }
      };
    }
    
    // Cre une nouvelle classe
    let User = makeClass("Hello");
    
    new User().sayHi(); // Hello

    Accesseurs/Mutateurs

    Tout comme les objets littraux, les classes peuvent inclure des accesseurs/mutateurs, des proprits values etc.

    Voici un exemple pour user.name implment en utilisant les proprits get/set :

    class User {
    
      constructor(name) {
        // invoque l'accesseur (the setter)
        this.name = name;
      }
    
      get name() {
        return this._name;
      }
    
      set name(value) {
        if (value.length < 4) {
          alert("Name is too short.");
          return;
        }
        this._name = value;
      }
    
    }
    
    let user = new User("John");
    alert(user.name); // John
    
    user = new User(""); // le nom est trop court.

    Techniquement, une telle dclaration de classe fonctionne en crant des getters et des setters dans User.prototype.

    Computed names []

    Voici un exemple avec un nom de mthode calcul utilisant des crochets [...] :

    class User {
    
      ['say' + 'Hi']() {
        alert("Hello");
      }
    
    }
    
    new User().sayHi();

    Ces caractristiques sont faciles retenir, car elles ressemblent celles dobjets littraux.

    Champs de classe

    Les anciens navigateurs peuvent avoir besoin de polyfill

    Les proprits de classe sont un ajout rcent au langage.

    Auparavant, nos classes navaient que des mthodes.

    Les Class fields (champs de classe) sont une syntaxe qui permet dajouter des proprits.

    Par exemple, ajoutons la proprit name class User :

    class User {
      name = "John";
    
      sayHi() {
        alert(`Hello, ${this.name}!`);
      }
    }
    
    new User().sayHi(); // Hello, John!

    Il suffit donc dcrire = dans la dclaration, et cest tout.

    La diffrence importante des champs de classe est quils sont dfinis sur des objets individuels, et non sur User.prototype :

    class User {
      name = "John";
    }
    
    let user = new User();
    alert(user.name); // John
    alert(User.prototype.name); // undefined

    Nous pouvons galement attribuer des valeurs laide dexpressions et dappels de fonctions plus complexes :

    class User {
      name = prompt("Name, please?", "John");
    }
    
    let user = new User();
    alert(user.name); // John

    Cration de mthodes lies avec des champs de classe

    Comme dmontr dans le chapitre Le "bind" de fonction les fonctions en JavaScript ont un this dynamique. Cela dpend du contexte de lappel.

    Donc, si une mthode objet est contourne et appele dans un autre contexte, this ne sera plus une rfrence son objet.

    Par exemple, ce code affichera undefined :

    class Button {
      constructor(value) {
        this.value = value;
      }
    
      click() {
        alert(this.value);
      }
    }
    
    let button = new Button("hello");
    
    setTimeout(button.click, 1000); // undefined

    Le problme est appel perdre le this.

    Il existe deux approches pour le corriger, comme indiqu dans le chapitre Le "bind" de fonction :

    1. Passer une fonction wrapper, telle que setTimeout(() => button.click(), 1000).
    2. Lier la mthode lobjet, par exemple dans le constructeur.

    Les champs de classe fournissent une syntaxe plus lgante :

    class Button {
      constructor(value) {
        this.value = value;
      }
      click = () => {
        alert(this.value);
      }
    }
    
    let button = new Button("hello");
    
    setTimeout(button.click, 1000); // hello

    Le champ de classe click = () => {...} est cr par objet, il y a une fonction distincte pour chaque objet Button, avec this lintrieur rfrenant cet objet. Nous pouvons passer button.click nimporte o, et la valeur de this sera toujours correcte.

    Cest particulirement utile dans un environnement de navigateur, pour les couteurs dvnements.

    Rsum

    La syntaxe de base dune classe ressemble ceci :

    class MyClass {
      prop = value; // proprit
    
      constructor(...) { // constructeur
        // ...
      }
    
      method(...) {} // mthode
    
      get something(...) {} //  mthode dfinie avec un accesseur
      set something(...) {} //  mthode dfinie avec un mutateur
    
      [Symbol.iterator]() {} // mthode avec un nom valu (symbole ici)
      // ...
    }

    MyClass est techniquement une fonction (celle que nous fournissons en tant que constructor), tandis que les mthodes, accesseurs et mutateurs sont crits dans MyClass.prototype.

    Dans les prochains chapitres nous apprendrons plus propos des classes, y compris la notion dhritage et les autres caractristiques.

    Exercices

    importance: 5

    La classe Clock (voir la sandbox) est crite en style fonctionnelle. Rcrivez la en syntaxe de classe.

    P.S. La montre doit tictaquer dans la console, ouvrez la pour la voir.

    Open a sandbox for the task.

    solution
    class Clock {
      constructor({ template }) {
        this.template = template;
      }
    
      render() {
        let date = new Date();
    
        let hours = date.getHours();
        if (hours < 10) hours = '0' + hours;
    
        let mins = date.getMinutes();
        if (mins < 10) mins = '0' + mins;
    
        let secs = date.getSeconds();
        if (secs < 10) secs = '0' + secs;
    
        let output = this.template
          .replace('h', hours)
          .replace('m', mins)
          .replace('s', secs);
    
        console.log(output);
      }
    
      stop() {
        clearInterval(this.timer);
      }
    
      start() {
        this.render();
        this.timer = setInterval(() => this.render(), 1000);
      }
    }
    
    
    let clock = new Clock({template: 'h:m:s'});
    clock.start();

    Ouvrez la solution dans une sandbox.

    Carte du tutoriel

    Commentaires

    lire ceci avant de commenter
    • Si vous avez des amliorations suggrer, merci de soumettre une issue GitHub ou une pull request au lieu de commenter.
    • Si vous ne comprenez pas quelque chose dans l'article, merci de prciser.
    • Pour insrer quelques bouts de code, utilisez la balise <code>, pour plusieurs lignes enveloppez-les avec la balise <pre>, pour plus de 10 lignes - utilisez une sandbox (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page