Class fields

Cette fonction est expérimentale
Puisque cette fonction est toujours en développement dans certains navigateurs, veuillez consulter le tableau de compatibilité pour les préfixes à utiliser selon les navigateurs.
Il convient de noter qu'une fonctionnalité expérimentale peut voir sa syntaxe ou son comportement modifié dans le futur en fonction des évolutions de la spécification.

Note : Les déclarations de champs privés et public sont une fonctionnalité expérimentale (proposition de niveau 3) proposée au TC39 (le comité JavaScript qui standard). La prise en charge des navigateurs est limitée mais cette fonctionnalité peut être utilisée via des systèmes de compilation tels que Babel. Voir le tableau de compatibilité ci-aprés.

Champs publics

Les champs publiques, qu'ils soient statiques ou rattachés aux instances, sont des propriétés accessibles en écriture, énumérables et configurables. Ainsi, à la différence de leurs homologues privés, elles participent à l'héritage prototypique.

Champs publics statiques

Les champs statiques publiques sont utiles lorsqu'on veut qu'un champ existe pour la classe dans son ensemble mais pas sur chaque instance créée. Cela est utile pour des caches, des configurations fixes ou pour d'autres données qu'on ne souhaiterait pas répliquer parmi les instances.

Les champs statiques publics sont déclarés avec le mot-clé static. Ils sont ajoutés au constructeur de la classe au moment de l'évaluation de la classe avec Object.defineProperty(). Pour y accéder, on utilise le constructeur de la classe.

class ClasseAvecChampStatique {
  static champStatique = 'champ statique';
}

console.log(ClasseAvecChampStatique.champStatique);
// devrait afficher "champ statique"​ dans la console

Les champs qui ne sont pas initialisés valent undefined.

class ClasseAvecChampStatique {
  static champStatique;
}

console.assert(ClasseAvecChampStatique.hasOwnProperty('champStatique'));
console.log(ClasseAvecChampStatique.champStatique);
// devrait afficher "undefined" dans la console

Les champs publics statiques ne sont pas réinitialisés avec les classes filles. En revanche, on peut y accéder via la chaîne de prototypes.

class ClasseAvecChampStatique {
  static champStatiqueBase = 'champ de base';
}

class SousClasseAvecChampStatique extends ClasseAvecChampStatique {
  static champStatiqueSousClasse = 'champ de sous-classe';
}

console.log(SousClasseAvecChampStatique.champStatiqueSousClasse);
// devrait afficher "champ de sous-classe" dans la console

console.log(SousClasseAvecChampStatique.champStatiqueBase);
// devrait afficher "champ de base" dans la console

Lorsqu'on initialise les champs, le mot-clé this fait référence au constructeur de la classe. On peut utiliser le mot-clé super afin d'obtenir le constructeur de la classe mère s'il existe :

class ClasseAvecChampStatique {
  static champStatiqueBase = 'champ de base statique';
  static autreChampStatiqueBase = this.champStatiqueBase;

  static méthodeStatiqueBase() { return 'sortie de la méthode statique de base'; }
}

class SousClasseAvecChampStatique extends ClasseAvecChampStatique {
  static champStatiqueSousClasse = super.méthodeStatiqueBase();
}

console.log(ClasseAvecChampStatique.autreChampStatiqueBase);
// devrait afficher "champ de base statique" dans la console

console.log(SousClasseAvecChampStatique.champStatiqueSousClasse);
// devrait afficher "sortie de la méthode statique de base" dans la console

Champs publics liés à l'instance

Les champs publics d'instance existent pour chaque instance d'une classe. En déclarant un champ public, on peut s'assurer que celui-ci est toujours présent. La définition de la classe permet également de documenter.

Les champs publics des instances sont ajoutés grâce à Object.defineProperty() ou dans le constructeur de la classe ou après le résultat super() pour une classe fille.

class ClasseAvecChampInstance {
  champInstance = 'champ instance';
}

const instance = new ClasseAvecChampInstance();
console.log(instance.champInstance);
// devrait afficher "champ instance" dans la console

Les champs qui ne sont pas initialisés explicitement vaudront undefined.

class ClasseAvecChampInstance {
  champInstance ;
}

const instance = new ClasseAvecChampInstance();
console.assert(instance.hasOwnProperty('champInstance'));
console.log(instance.champInstance);
// devrait afficher "undefined" dans la console

À l'instar des propriétés, on peut calculer les noms des champs :

const PREFIXE = 'préfixe';

class ClasseAvecNomChampCalculé {
    [`${PREFIXE}Champ`] = 'champ préfixé';
}

const instance = new ClasseAvecNomChampCalculé();
console.log(instance.préfixeChamp);
// devrait afficher "champ préfixé" dans la console

Lorsqu'on utilise this pour l'initialisation des champs, celui-ci fait référence à l'instance en cours de construction. À l'intérieur d'une sous-classe, on pourra accéder au prototype de la classe parente avec le mot-clé super.

class ClasseAvecChampInstance {
  champInstanceBase = 'base field';
  autreChampInstanceBase = this.champInstanceBase;
  méthodeInstanceBase() { return 'sortie méthode base'; }
}

class SousClasseAvecChampInstance extends ClasseAvecChampInstance {
  champClasseFille = super.méthodeInstanceBase();
}

const base = new ClasseAvecChampInstance();
const sub = new SousClasseAvecChampInstance();

console.log(base.autreChampInstanceBase);
// devrait afficher "base field" dans la console

console.log(sub.champClasseFille);
// devrait afficher "sortie méthode base" dans la console

Méthodes publiques

Méthodes publiques statiques

The static keyword defines a static method for a class. Static methods aren't called on instances of the class. Instead, they're called on the class itself. These are often utility functions, such as functions to create or clone objects.

The static methods are added to the class constructor with Object.defineProperty at class evaluation time. These methods are writable, non-enumerable and configurable.

Méthodes publiques rattachées aux instances

As the name implies, public instance methods are methods available on class instances.

class ClassWithPublicInstanceMethod {
  publicMethod() {
    return 'hello world';
  }
}

const instance = new ClassWithPublicInstanceMethod();
console.log(instance.publicMethod());
// expected output: "hello worl​d"

Public instance methods are added to the class prototype at the time of class evaluation using Object.defineProperty. They are writable, non-enumerable, and configurable.

You may make use of generator, async and async generator functions.

class ClassWithFancyMethods {
  *generatorMethod() { }
  async asyncMethod() { }
  async *asyncGeneratorMethod() { }
}

Inside instance methods, this refers to the instance itself. In subclasses, super lets you access the superclass prototype, allowing you to call methods from the superclass.

class BaseClass {
  msg = 'hello world';
  basePublicMethod() {
    return this.msg;
  }
}

class SubClass extends BaseClass {
  subPublicMethod() {
    return super.basePublicMethod();
  }
}

const instance = new SubClass();
console.log(instance.subPublicMethod());
// expected output: "hello worl​d"

Getters and setters are special methods that bind to a class property, and are called when that property is accessed or set. Use the get and set syntax to declare a public instance getter or setter.

class ClassWithGetSet {
  #msg = 'hello world';
  get msg() {
    return this.#msg;
  }
  set msg(x) {
    this.#msg = `hello ${x}`;
  }
}

const instance = new ClassWithGetSet();
console.log(instance.msg);
// expected output: "hello worl​d"

instance.msg = 'cake';
console.log(instance.msg);
// expected output: "hello cake"

Champs privés

Champs privés statiques

Private fields are accessible on the class constructor from inside the class declaration itself.

The limitation of static variables being called by only static methods still holds.

class ClassWithPrivateStaticField {
  static #PRIVATE_STATIC_FIELD;

  static publicStaticMethod() {
    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
  }
}

assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);

Private static fields are added to the class constructor at class evaluation time.

There is a provenance restriction on private static fields. Only the class which defines the private static field can access the field. This can lead to unexpected behaviour when using this

class BaseClassWithPrivateStaticField {
  static #PRIVATE_STATIC_FIELD;

  static basePublicStaticMethod() {
    this.#PRIVATE_STATIC_FIELD = 42;
    return this.#PRIVATE_STATIC_FIELD;
  }
}

class SubClass extends BaseClassWithPrivateStaticField { }

assertThrows(() => SubClass.basePublicStaticMethod(), TypeError);

Champs privés relatifs aux instances

Private instance fields are declared with # names ( pronounced "hash names"), which are identifiers prefixed with #. The # is a part of the name itself and is used for declaration and accessing as well.

The encapsulation is enforced by the language. It is a syntax error to refer to # names not in scope.

class ClassWithPrivateField {
  #privateField;
  
  constructor() {
    this.#privateField = 42;
    this.#randomField = 666; # Syntax error
  }
}

const instance = new ClassWithPrivateField();
instance.#privateField === 42; // Syntax error

Méthodes privées

Méthodes privées statiques

Like their public equivalent, private static methods are called on the class, not instances of the class. Like private static fields, they are only accessible from inside the class declaration.

Private static methods may be generator, async and async generator functions.

class ClassWithPrivateStaticMethod {
    static #privateStaticMethod() {
        return 42;
    }

    static publicStaticMethod() {
        return ClassWithPrivateStaticMethod.#privateStaticMethod();
    }
}

assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);

Méthodes privées relatives aux instances

Private instance methods are methods available on class instances whose access is restricted in the same manner as private instance fields.

class ClassWithPrivateMethod {
  #privateMethod() {
    return 'hello world';
  }

  getPrivateMessage() {
      return #privateMethod();
  }
}

const instance = new ClassWithPrivateMethod();
console.log(instance.getPrivateMessage());
// expected output: "hello worl​d"

Private instance methods may be generator, async or async generator functions. Private getters and setters are also possible:

class ClassWithPrivateAccessor {
  #message;

  get #decoratedMessage() {
    return `✨${this.#message}✨`;
  }
  set #decoratedMessage(msg) {
    this.#message = msg;
  }

  constructor() {
    this.#decoratedMessage = 'hello world';
    console.log(this.#decoratedMessage);
  }
}

new ClassWithPrivateAccessor();
// expected output: "✨hello worl​d✨"

Compatibilité des navigateurs

Champs de classe publics

Update compatibility data on GitHub
OrdinateurMobileServeur
ChromeEdgeFirefoxInternet ExplorerOperaSafariWebview AndroidChrome pour AndroidFirefox pour AndroidOpera pour AndroidSafari sur iOSSamsung InternetNode.js
Public class fieldsChrome Support complet 72Edge Aucun support NonFirefox Support complet 69IE Aucun support NonOpera Support complet 60Safari Aucun support NonWebView Android Support complet 72Chrome Android Support complet 72Firefox Android Aucun support NonOpera Android Support complet 51Safari iOS Aucun support NonSamsung Internet Android Aucun support Nonnodejs Support complet 12.0.0

Légende

Support complet  
Support complet
Aucun support  
Aucun support

Champs de classe privés

Update compatibility data on GitHub
OrdinateurMobileServeur
ChromeEdgeFirefoxInternet ExplorerOperaSafariWebview AndroidChrome pour AndroidFirefox pour AndroidOpera pour AndroidSafari sur iOSSamsung InternetNode.js
Private class fieldsChrome Support complet 74Edge Aucun support NonFirefox Aucun support NonIE Aucun support NonOpera Support complet 62Safari Aucun support NonWebView Android Support complet 74Chrome Android Support complet 74Firefox Android Aucun support NonOpera Android Support complet 53Safari iOS Aucun support NonSamsung Internet Android Aucun support Nonnodejs Support complet 12.0.0

Légende

Support complet  
Support complet
Aucun support  
Aucun support

Voir aussi