En Javascript, les proxys vous permettent d'intercepter des opérations d'objet spécifiques et de les personnaliser. Le Proxy agit comme intermédiaire entre l'objet et le « monde réel ». Ainsi, vous pouvez améliorer les opérations de base d'un objet pour implémenter une logique plus complexe ou redéfinir les opérations fondamentales pour répondre à vos besoins.
Les cas d'utilisation incluent :
Le proxy prend deux paramètres :
const target = { greeting1: "Hello", greeting2: "Good morning" } const handler = { get(target, prop, receiver) { return target[prop] " friends!" } } const proxy = new Proxy(target, handler) console.log(proxy.greeting1) // Hello friends! console.log(proxy.greeting2) // Good morning friends!
Dans cet exemple, nous définissons un proxy. L'objet cible a deux propriétés. Nous définissons un gestionnaire qui fournit une implémentation du gestionnaire get(). Le piège get intercepte l'accès à n'importe quelle propriété de l'objet cible, et à l'intérieur de celui-ci, nous pouvons modifier le comportement si nécessaire.
Avec cette configuration, cela signifie que chaque fois que nous allons accéder aux propriétés de l'objet cible, le gestionnaire l'intercepte et exécute le code que nous avons implémenté. Dans notre cas, cela prend simplement la valeur de la propriété et ajoute des amis !.
Souvent, les proxys sont utilisés avec l'API Reflect. Reflect fournit des méthodes portant les mêmes noms que les interruptions proxy. Comme son nom l'indique, il reflète la sémantique d'appel des méthodes internes de l'objet correspondant.
const target = { greeting1: "Hello", greeting2: "Good morning" } const handler = { get(target, prop, receiver) { return Reflect.get(...arguments) " friends!" } } const proxy = new Proxy(target, handler) console.log(proxy.greeting1) // Hello friends! console.log(proxy.greeting2) // Good morning friends!
Reflect n'est pas obligé d'utiliser des proxys mais l'utilisation de Reflect nous permet d'être sûr que le comportement correspond aux opérations du moteur Javascript natif. Il garantit également la compatibilité avec les futures mises à jour, évite les effets secondaires involontaires et simplifie le code. Sans cela, le développeur devrait réimplémenter des comportements tels que l'accès aux propriétés, l'affectation, la suppression... qui peuvent être sujets aux erreurs et incompatibles avec le comportement natif de Javascript.
Créons quelques exemples pour explorer ce que nous pouvons faire avec Proxy.
Dans notre premier exemple, disons que nous souhaitons enregistrer les actions effectuées sur un objet. Chaque fois que nous obtenons, définissons ou supprimons une propriété, je souhaite l'imprimer sur la console. Cela pourrait être utile à des fins de débogage.
const target = { name: "Damien", age: 32, status: "WRITING" } const loggerHandler = { get(target, prop, receiver) { if (prop in target) { console.log(`[LOG] Accessing property ${prop}. Current value is ${target[prop]}`) return Reflect.get(...arguments) } else { console.error(`[LOG] Error accessing non-existent property ${prop}`) } }, set(target, key, value) { console.log(`[LOG] Setting property ${key}. New value: ${value}`) return Reflect.set(...arguments) }, deleteProperty(target, prop) { console.warn(`[LOG] Deleting property: ${prop}`) return Reflect.deleteProperty(...arguments) } } const proxy = new Proxy(target, loggerHandler) proxy.name // [LOG] Accessing property name. Current value is Damien proxy.status // [LOG] Accessing property status. Current value is WRITING proxy.name = "Bob" // [LOG] Setting property name. New value: Bob proxy.status = "NAPPING" // [LOG] Setting property status. New value: NAPPING proxy.job = "Developer" // [LOG] Setting property job. New value: Developer delete proxy.job // [LOG] Deleting property: job proxy.job // [LOG] Error accessing non-existent property job
Nous avons défini un loggerHandler qui redéfinit 3 opérations fondamentales : get, set et delete. Pour chaque action, nous enregistrons quelque chose sur la console décrivant ce qui se passe. La beauté du proxy, c'est que nous n'avons pas besoin d'écrire l'instruction de la console à chaque fois. Nous interagissons avec notre objet comme nous le faisons toujours, et le proxy s'occupe du comportement de journalisation. Plutôt cool non ?
Dans notre deuxième exemple, nous utiliserons un proxy pour effectuer des validations d'entrée pour les données de formulaire.
const validationRules = { name: value => value.length >= 3 || "Name must be at least 3 characters long", age: value => Number.isInteger(value) || "Age must be a number", email: value => value.includes('@') || "Enter a valid email" } let formData = { name: "", age: null, email: "" } const formHandler = { set(target, key, value) { if (typeof value === "string") { value = value.trim() } const validationResult = validationRules[key](value) if (validationResult !== true) { console.error(`Validation failed for property ${key}: ${validationResult}`) return false; } return Reflect.set(...arguments) } } const formProxy = new Proxy(formData, formHandler) formProxy.age = "32 years old" // Validation failed for property age: Age must be a number formProxy.name = "Da" // Validation failed for property name: Name must be at least 3 characters long formProxy.email = "damcoss mail.com" // Validation failed for property email: Enter a valid email formProxy.age = 32 // OK formProxy.name = "Damien" // OK formProxy.email = "[email protected]" // OK
Nous définissons ici un objet avec différentes méthodes utilisées pour valider si les valeurs sont valides ou non. Ensuite, nous utilisons la même logique. Nous avons notre objet cible formData que nous voulons proxy. Dans le formHandler, nous redéfinissons la méthode set() pour appliquer nos règles de validation sur les valeurs d'entrées.
Les proxys, combinés à l'API Reflect, sont des outils flexibles et puissants pour intercepter et personnaliser les opérations sur les objets. En les utilisant, vous pouvez améliorer et contrôler le comportement de manière dynamique. En utilisant l'API Reflect, vous vous assurez également que le comportement est cohérent avec le moteur Javascript.
Les proxys sont souvent utilisés dans les bibliothèques et les frameworks pour permettre des comportements avancés tels que la programmation réactive, les wrappers d'API et l'observation des propriétés.
Amusez-vous bien ❤️
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3