#champ

Les champs et méthodes préfixés par # sont privés : seul le code à l’intérieur de la classe peut y accéder.

Sur cette page

Exemple

#
JavaScript
class FuelTank {
  #fuel = 10

  use(amount) {
    if (amount > this.#fuel) return false
    this.#fuel -= amount
    return true
  }

  get fuel() {
    return this.#fuel
  }
}

const tank = new FuelTank()

console.log(tank.use(3))
console.log(tank.use(20))
console.log(tank.fuel)
console.log(tank)
console.log(Object.keys(tank))
Console
true
false
7
FuelTank {}
[]

Définition et utilisation

#

Un nom de champ ou de méthode commençant par # désigne un membre privé. Il ne peut être utilisé que dans le corps de la classe où il a été déclaré. Une référence objet.#champ depuis l’extérieur est une erreur de syntaxe, signalée avant même que le code ne s’exécute.

C’est une véritable confidentialité, pas seulement une convention comme avec le préfixe _champ. Les champs privés n’apparaissent ni dans Object.keys(), ni dans JSON.stringify(), ni dans une boucle for...in, et du code extérieur à la classe ne peut ni les lire ni les modifier. C’est la classe seule qui décide ce qu’elle expose, par exemple via des méthodes ou des getters.

Un champ privé doit être déclaré dans le corps de la classe, par exemple #coins = 0 ou simplement #password, avant d’être utilisé. Les méthodes (#validate()), les getters et les membres statiques peuvent aussi être privés. Les classes dérivées ne voient pas les champs privés du parent, et l’opérateur #champ in objet vérifie si un objet possède ce champ privé.

Syntaxe

#
Syntaxe
class Name {
  #field = value
  static #staticField = value

  #method() {}

  read() {
    return this.#field
  }

  static isName(obj) {
    return #field in obj
  }
}

Plus d’exemples

#
Une méthode privée
JavaScript
class Account {
  #password

  constructor(login, password) {
    this.login = login
    this.#password = this.#hash(password)
  }

  #hash(text) {
    return [...text].reverse().join('')
  }

  checkPassword(attempt) {
    return this.#hash(attempt) === this.#password
  }
}

const account = new Account('lea', 'secret123')

console.log(account.checkPassword('secret123'))
console.log(account.checkPassword('mot de passe'))
console.log(JSON.stringify(account))
Console
true
false
{"login":"lea"}

Inverser la chaîne n’est qu’une illustration. Les vrais mots de passe sont sécurisés par des fonctions de hachage côté serveur, pas dans le navigateur.

Vérifier avec #champ in
JavaScript
class Badge {
  #id

  constructor(id) {
    this.#id = id
  }

  static isBadge(value) {
    return #id in value
  }
}

console.log(Badge.isBadge(new Badge(7)))
console.log(Badge.isBadge({ id: 7 }))
Console
true
false
Piège : _champ n’est qu’une convention
JavaScript
class OldWallet {
  constructor() {
    this._coins = 100
  }
}

class NewWallet {
  #coins = 100
}

const oldWallet = new OldWallet()
oldWallet._coins = 1000000

console.log(oldWallet)
console.log(new NewWallet())
Console
OldWallet { _coins: 1000000 }
NewWallet {}

Le trait de soulignement suggère seulement que le champ ne doit pas être touché, mais n’importe quel code peut le modifier. Le champ #coins, lui, ne peut même pas être lu depuis l’extérieur.

Compatibilité des navigateurs

#

Largement disponible · depuis 2021

Fonctionne dans tous les navigateurs modernes, y compris sur mobile. Vous pouvez l’utiliser sans crainte.

  • Chrome
  • Edge
  • Firefox
  • Safari

Bonnes pratiques

#
  • Déclarez chaque champ privé dans le corps de la classe avant de lui affecter une valeur. Écrire seulement this.#champ = x dans le constructeur, sans déclaration, est une erreur de syntaxe.
  • Les champs privés ne se retrouvent ni dans JSON.stringify() ni dans une copie { ...obj }. Si les données doivent atteindre une API, ajoutez une méthode toJSON() qui renvoie ce que vous voulez envoyer.
  • La confidentialité s’applique à la classe, pas à un seul objet. Une méthode de la classe peut lire le #champ d’une autre instance de la même classe, par exemple pour comparer a.#id === b.#id.

Entrées associées

#

Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.