W3docs

JavaScript Proxy et Reflect

Apprenez comment fonctionnent JavaScript Proxy et Reflect : interceptez get, set, apply, has et delete avec des traps, et appliquez des proxies pour la validation, le contrôle d'accès et la journalisation.

Les proxies JavaScript vous permettent d'intercepter et de redéfinir les opérations fondamentales sur les objets — lire une propriété, l'écrire, vérifier si une clé existe, appeler une fonction, et bien plus. Associés à l'API Reflect, qui effectue ces mêmes opérations de manière « par défaut », les proxies offrent un mécanisme propre et officiel pour ajouter des comportements aux objets sans les modifier directement.

Ce chapitre couvre ce qu'est un proxy, les traps les plus courants (get, set, apply, has, deleteProperty), comment Reflect complète les proxies, ainsi que plusieurs patterns concrets tels que la validation, le contrôle d'accès et la journalisation.

Qu'est-ce qu'un Proxy

Un Proxy enveloppe un objet cible et un handler. Le handler est un ensemble de fonctions appelées traps, chacune interceptant une opération spécifique. Lorsque vous interagissez avec le proxy, le trap correspondant s'exécute à la place du comportement par défaut ; si aucun trap n'est défini pour une opération, le proxy la transmet à la cible sans modification.

Cela s'avère utile chaque fois que vous souhaitez superposer des comportements transversaux — journalisation, validation, valeurs par défaut, règles d'accès — sur un object sans toucher à son propre code.

Syntaxe de Proxy

const proxy = new Proxy(target, handler);
  • target : L'object original dont vous souhaitez intercepter les opérations.
  • handler : Un object dont les méthodes (traps) définissent le comportement des opérations.

Vous utilisez ensuite proxy exactement comme vous utiliseriez l'object original ; la différence est que vos traps s'exécutent entre les deux.

Comprendre le trap get

Le trap get intercepte les lectures de propriétés sur l'object cible. Il reçoit la target, la clé property et le receiver (le proxy lui-même). Il est souvent utilisé pour journaliser les accès, calculer des propriétés à la volée, ou retourner des valeurs par défaut pour les clés manquantes.

Exemple :

javascript— editable

Ce code configure un proxy pour journaliser les accès aux propriétés d'un object.

  • Handler : Définit un trap get pour journaliser la propriété accédée.
  • Object cible : Contient les propriétés name et age.
  • Proxy : Enveloppe l'object target avec le handler.

Lorsque proxy.name est accédé, il journalise "Getting name" et retourne "John". Cela est utile pour surveiller ou déboguer les accès aux propriétés.

Manipulation des opérations sur les objets avec les traps set et apply

Le trap set

Le trap set peut imposer des règles pour les affectations de propriétés, garantissant que les propriétés contiennent des types spécifiques ou satisfont certaines conditions.

Exemple :

javascript— editable

Ce code configure un proxy pour valider et journaliser les affectations de propriétés sur un object.

  • Handler : Définit un trap set pour vérifier la propriété age avec des valeurs valides et journaliser les tentatives de modification.
  • Proxy : Enveloppe l'object target avec le handler.

Lorsque proxy.age est défini, il vérifie s'il s'agit d'un âge valide (0-150). Si invalide, il journalise une erreur et lève une exception.

Le trap apply

La méthode apply dans un JavaScript Proxy intercepte les appels de fonctions. Elle prend trois arguments :

  1. target : La fonction originale appelée.
  2. thisArg : La valeur de this à l'intérieur de la fonction.
  3. argumentsList : Un array d'arguments passés à la fonction.

Exemple :

javascript— editable

Ce code configure un proxy pour journaliser les appels de fonctions et leurs arguments.

  • Handler : Définit un trap apply pour journaliser les arguments lorsque la fonction est appelée.
  • Fonction : sum additionne deux nombres.
  • Proxy : Enveloppe la fonction sum avec le handler.

Dans le code fourni, le trap apply journalise les arguments puis appelle la fonction originale via target.apply(thisArg, argumentsList). Cela est utile pour la journalisation, le débogage, ou la modification dynamique du comportement des fonctions.

Le trap has

Le trap has intercepte l'opérateur in. Une utilisation courante consiste à masquer les clés « privées » (par convention, les noms commençant par _) afin qu'elles ne semblent pas exister de l'extérieur.

Exemple :

javascript— editable

Même si _secret existe toujours sur la cible, l'opérateur in retourne false, de sorte que la clé est effectivement masquée du code qui sonde l'object.

Le trap deleteProperty

Le trap deleteProperty intercepte l'opérateur delete, vous permettant de protéger certaines clés contre la suppression. Il doit retourner true lorsque la suppression est autorisée, ou lever une exception pour la bloquer en mode strict.

Exemple :

javascript— editable
Avertissement

Les proxies JavaScript sont puissants, mais utilisez-les avec discernement. Un usage excessif des proxies peut rendre votre code plus difficile à comprendre et à maintenir. Notez que les proxies introduisent une légère surcharge de performance par rapport aux objets natifs.

L'API Reflect

Reflect est un objet intégré qui fournit une méthode pour chaque opération interceptable — exactement le même ensemble que celui couvert par les traps de proxy (Reflect.get, Reflect.set, Reflect.has, Reflect.deleteProperty, Reflect.apply, etc.). Chaque méthode exécute la version par défaut de cette opération.

Cela fait de Reflect le compagnon naturel de Proxy : à l'intérieur d'un trap, vous souhaitez généralement ajouter un comportement puis laisser l'opération se dérouler normalement. Appeler la méthode Reflect correspondante fait exactement cela, et elle transmet correctement le receiver (important pour les getters/setters), ce qu'un simple target[property] ne fait pas. Vous verrez ce pattern utilisé dans les exemples pratiques ci-dessous.

Les méthodes Reflect retournent également des valeurs au lieu de lever des exceptions — par exemple Reflect.set retourne un boolean indiquant le succès — ce qui rend les opérations plus prévisibles que leurs équivalents opérateurs ou Object.*.

Voici un aperçu rapide des principales méthodes Reflect :

1. Reflect.get()

Cette méthode est utilisée pour obtenir la valeur d'une propriété d'un object.

Exemple :

javascript— editable

2. Reflect.set()

Cette méthode est utilisée pour définir la valeur d'une propriété sur un object.

Exemple :

javascript— editable

3. Reflect.has()

Cette méthode vérifie si une propriété existe dans un object.

Exemple :

javascript— editable

4. Reflect.deleteProperty()

Cette méthode supprime une propriété d'un object.

Exemple :

javascript— editable

5. Reflect.ownKeys()

Cette méthode retourne toutes les clés de propriétés propres d'un object.

Exemple :

javascript— editable

6. Reflect.apply()

Cette méthode appelle une fonction cible avec les arguments donnés.

Exemple :

javascript— editable

7. Reflect.construct()

Cette méthode est utilisée pour créer une nouvelle instance d'un object.

Exemple :

javascript— editable

Ces exemples montrent comment vous pouvez utiliser les méthodes Reflect pour effectuer des opérations courantes sur les objets de manière plus propre et plus cohérente.

Cas d'utilisation pratiques des proxies JavaScript

Exemple 1 : Initialisation automatique des propriétés

Description : Utilisez les proxies JavaScript pour initialiser automatiquement les propriétés undefined dans un object. Cela peut être utile dans des situations où les objets sont remplis dynamiquement avec des données au fil du temps, comme les paramètres utilisateur ou les configurations qui peuvent ne pas être définis initialement.

javascript— editable

Ce code crée un proxy qui vérifie si une propriété existe sur un object. Si ce n'est pas le cas, le proxy définit automatiquement une valeur par défaut. Cela aide à prévenir les erreurs liées aux propriétés manquantes.

Exemple 2 : Contrôle d'accès

Description : Les proxies peuvent imposer des permissions de lecture ou d'écriture sur les propriétés d'un object. Cet exemple démontre un proxy qui empêche la lecture ou l'écriture de certaines propriétés en fonction de règles prédéfinies, ce qui est particulièrement utile pour gérer l'accès aux données sensibles.

javascript— editable

Ce code sécurise un object en contrôlant l'accès à ses propriétés. Il bloque la lecture de 'sensitiveData' et empêche la modification des propriétés 'readOnly', contribuant à protéger les données.

Exemple 3 : Journalisation et débogage

Description : Les proxies peuvent être utilisés pour journaliser les interactions avec un object, ce qui aide au débogage et à la surveillance des opérations. Cet exemple crée un proxy qui journalise toutes les opérations get, set et les appels de méthodes effectués sur un object.

javascript— editable

Ce code suit chaque fois que quelqu'un accède à une propriété de l'object ou la modifie, ce qui est idéal pour comprendre ce que fait votre code et quand.

Exemple 4 : Validation des données

Description : Utilisez les proxies pour la validation à la volée des propriétés d'un object. Cela est particulièrement utile pour garantir l'intégrité des données lorsque les objets sont mis à jour dynamiquement dans une application.

javascript— editable

Cet exemple démontre comment utiliser le Proxy de JavaScript pour valider et journaliser les changements de propriétés. L'object validator vérifie si la propriété age est un nombre valide compris entre 0 et 150. Si ce n'est pas le cas, il journalise une erreur et lève une exception. Sinon, il journalise la nouvelle valeur et met à jour la propriété. L'object person utilise ce validateur pour gérer sa propriété age, garantissant que les âges invalides sont détectés et journalisés.

Conclusion

Maîtriser les proxies JavaScript vous permet de contrôler et d'étendre le comportement des objets sans les modifier directement. Les proxies peuvent imposer des règles de validation et d'accès, fournir des valeurs par défaut, et alimenter des outils de journalisation ou de débogage, tandis que Reflect maintient les opérations sous-jacentes propres et prévisibles. Utilisés avec parcimonie, ils vous aident à créer des applications plus dynamiques et sécurisées.

Pour approfondir les opérations que les proxies interceptent, consultez les getters et setters de propriétés et les indicateurs et descripteurs de propriétés. Pour le pattern de validation présenté ci-dessus, la gestion des erreurs avec try...catch et les classes sont des compagnons utiles.

Exercices

Pratique
Quelle est la fonctionnalité principale des objets Proxy et Reflect de JavaScript ?
Quelle est la fonctionnalité principale des objets Proxy et Reflect de JavaScript ?
Was this page helpful?