W3docs

L'opérateur new en JavaScript

Apprenez comment les fonctions constructeurs et l'opérateur new créent des objets en JavaScript : étapes, règle de retour, new.target et conventions.

Introduction aux constructeurs et à l'opérateur new

En JavaScript, les constructeurs sont des fonctions conçues pour initialiser des objets nouvellement créés. Ils jouent un rôle central dans la programmation orientée objet en permettant aux développeurs de définir les propriétés et les comportements que doivent avoir les objets d'une certaine classe. L'opérateur new sert à créer une instance d'un object à partir d'une fonction constructeur : il prépare un nouvel environnement d'object basé sur le prototype spécifié et exécute le constructeur pour initialiser le nouvel object.

Fonctionnement des constructeurs

Une fonction constructeur en JavaScript ressemble à n'importe quelle autre fonction, mais elle commence conventionnellement par une majuscule pour la distinguer des fonctions ordinaires. Lorsque l'opérateur new invoque une fonction constructeur, quatre choses se produisent en coulisses, ce qui correspond approximativement au pseudo-code suivant :

function User(name) {
  // this = {};  (1) an empty object is created and assigned to this
  // this.__proto__ = User.prototype;  (2) prototype is linked

  this.name = name;  // (3) the constructor body runs, adding properties to this

  // return this;  (4) this is returned automatically
}
  1. Un nouvel object vide est créé et assigné à this.
  2. Le prototype est lié : le [[Prototype]] interne du nouvel object est défini sur la propriété prototype du constructeur, de sorte qu'il hérite des propriétés et des méthodes qui y sont définies.
  3. Le corps du constructeur s'exécute : la fonction s'exécute avec les arguments que vous passez, et this fait référence au tout nouvel object, donc des assignations comme this.name = name lui attachent des propriétés.
  4. L'object est retourné : this est retourné automatiquement, sauf si le constructeur retourne explicitement un object différent (voir La règle de la valeur de retour ci-dessous).
Info

Le JavaScript moderne utilise la syntaxe class pour définir les constructeurs et les méthodes de façon plus intuitive. Cela offre une approche orientée classes plus lisible, similaire à d'autres langages de programmation.

Exemple : fonction constructeur de base

javascript— editable

Explication : Dans cet exemple, User est une fonction constructeur qui initialise name, age et une méthode greet sur les objets nouvellement créés. L'instruction new User('John', 30) crée une nouvelle instance de User avec le nom « John » et l'âge 30. À l'intérieur de greet, this fait référence à l'object sur lequel la méthode a été appelée.

La règle de la valeur de retour

Les constructeurs n'utilisent normalement pas return — le nouvel object (this) est retourné automatiquement. Mais return a un comportement spécial, facile à manquer, à l'intérieur d'un constructeur :

  • Si return est suivi d'un object, cet object est retourné à la place de this.
  • Si return est suivi d'une valeur primitive (string, nombre, boolean, undefined, etc.), elle est ignorée et this est retourné comme d'habitude.
javascript— editable

Explication : WithObject retourne un object simple, qui remplace donc entièrement l'instance. WithPrimitive retourne une string, qui est ignorée, et c'est donc le this original (avec name: 'Alice') qui est retourné. Vous vous appuierez rarement sur ce comportement, mais il explique des résultats surprenants lorsqu'un constructeur retourne accidentellement une valeur.

Détecter new avec new.target

À l'intérieur de n'importe quelle fonction, new.target vaut undefined lorsque la fonction est appelée normalement, et est égal à la fonction elle-même lorsqu'elle est appelée avec new. Cela permet à un constructeur de détecter comment il a été invoqué — utile pour imposer (ou autoriser silencieusement) le mot-clé new.

javascript— editable

Explication : Parce que Modal vérifie new.target, appeler Modal('Without new') sans new est redirigé de façon transparente vers new Modal(...), de sorte que b est quand même une vraie instance de Modal. (Remarque : beaucoup d'équipes préfèrent ne pas faire cela et laisser l'absence de new provoquer une erreur visible.)

Quand utiliser un constructeur ?

Utilisez une fonction constructeur (ou une class) lorsque vous devez créer de nombreux objets de même forme — plusieurs utilisateurs, voitures, widgets DOM, etc. Le constructeur centralise la logique d'initialisation pour que chaque instance soit construite de la même façon et partage les méthodes via le prototype.

Si vous n'avez besoin que d'un seul object, un littéral d'object simple { ... } est plus simple. Pour un object unique qui bénéficie quand même d'un corps de constructeur, vous pouvez même utiliser un constructeur anonyme :

javascript— editable

Explication : La function anonyme s'exécute une seule fois comme constructeur et n'est enregistrée nulle part, donc elle ne peut pas être réutilisée — c'est simplement une façon d'encapsuler une initialisation complexe à usage unique.

Fonctions constructeurs vs. classes

Le code moderne préfère généralement la syntaxe class, qui est essentiellement du sucre syntaxique par-dessus les fonctions constructeurs et les prototypes. Les deux extraits ci-dessous sont équivalents :

javascript— editable

Les classes apportent de vrais avantages par rapport aux fonctions constructeurs : les méthodes ne sont pas énumérables par défaut, le corps s'exécute en mode strict, appeler une classe sans new lève une erreur, et extends/super rendent l'héritage beaucoup plus propre. Les fonctions constructeurs restent importantes à comprendre, car les classes reposent sur le même mécanisme de prototype, et vous les rencontrerez encore dans du code ancien.

Utiliser les constructeurs pour des objets complexes

Les constructeurs peuvent être utilisés pour établir des relations plus complexes entre les objets, notamment des méthodes qui interagissent avec d'autres propriétés des objets.

Exemple : constructeur avec des méthodes

javascript— editable

Explication : Le constructeur Car configure chaque object voiture avec des propriétés spécifiques et une méthode qui affiche les informations relatives à la voiture.

Exemple : méthodes sur le prototype

javascript— editable

Explication : En ajoutant introduce au prototype d'Employee, toutes les instances partagent la même méthode, ce qui est plus économe en mémoire que de la définir directement dans le constructeur.

Avertissement

Il est recommandé d'utiliser les classes ES6 pour définir les objets et les constructeurs afin d'obtenir un code plus propre et plus lisible.

Bonnes pratiques avec les constructeurs

Lorsque vous travaillez avec des constructeurs en JavaScript, respecter certaines bonnes pratiques peut grandement améliorer la lisibilité, l'efficacité et la scalabilité de votre code. Vous trouverez ci-dessous ces pratiques détaillées avec des exemples et des explications approfondis :

1. Convention de nommage

Bonne pratique : Commencez toujours le nom d'un constructeur par une majuscule pour le différencier des fonctions ordinaires. C'est une convention courante en JavaScript et dans de nombreux autres langages de programmation qui aide les développeurs à identifier rapidement les fonctions constructeurs.

Exemple :

javascript— editable

Explication : La fonction constructeur Laptop commence par une majuscule, indiquant qu'elle est destinée à être utilisée avec l'opérateur new pour créer de nouveaux objets.

2. Séparation de la logique

Bonne pratique : Pour les méthodes qui n'ont pas besoin d'accéder aux données d'instance individuelles, définissez-les sur le prototype du constructeur plutôt qu'à l'intérieur du constructeur lui-même. Cette approche économise de la mémoire, car toutes les instances partagent la même méthode plutôt que chaque instance en créant une nouvelle en mémoire.

Exemple :

javascript— editable

Explication : La méthode describe est ajoutée au prototype de Book, ce qui signifie que toutes les instances de Book partagent la même méthode describe. C'est plus efficace que si describe était définie dans le constructeur, ce qui créerait une nouvelle fonction pour chaque instance de livre.

3. Valeurs de retour

Bonne pratique : Évitez de retourner des valeurs depuis les constructeurs. Les constructeurs JavaScript retournent automatiquement la nouvelle instance d'object, sauf si vous retournez explicitement un object différent. Retourner des valeurs non-object (comme une string ou un nombre) n'aura aucun effet, et la nouvelle instance sera quand même retournée.

Exemple :

javascript— editable

Explication : Malgré la tentative de retourner une string depuis le constructeur Player, JavaScript ignore cette valeur de retour car ce n'est pas un object. La nouvelle instance de Player est retournée comme prévu.

Conclusion

Comprendre et utiliser les constructeurs et l'opérateur new en JavaScript est essentiel pour une programmation orientée objet efficace. En suivant les conventions et les bonnes pratiques décrites ici, les développeurs peuvent créer un code organisé, efficace et scalable. Les constructeurs offrent un mécanisme puissant pour initialiser de nouveaux objets et définir leur comportement de façon structurée et intuitive.

Pour aller plus loin, explorez comment les constructeurs partagent des comportements via l'héritage prototypal, comment la syntaxe class s'appuie sur ces idées, et comment une fonction est aussi un object avec ses propres propriétés.

Entraînement

Pratique
Que se passe-t-il lorsqu'une fonction est exécutée avec 'new' en JavaScript ?
Que se passe-t-il lorsqu'une fonction est exécutée avec 'new' en JavaScript ?
Was this page helpful?