Métaprogrammation JavaScript
Métaprogrammation
La métaprogrammation fait référence à plusieurs façons dont un programme peut se manipuler lui-même :
- Modifier des objets à l'exécution
- Inspecter des objets à l'exécution
- Contrôler des objets à l'exécution
- Intercepter des opérations en cours d'exécution
- Modifier des fonctions et des classes
- Générer du code dynamique
L'explication facile
Normalement, le code gère des données .
Avec la métaprogrammation, le code gère du code .
Inspection des objets
Avec la méthode Object.keys() , vous pouvez inspecter les propriétés d'un objet .
Utiliser Object.keys() est un exemple simple de métaprogrammation.
Exemple
Ce code analyse un autre morceau de code (un objet) :
// Créer un objet
const user = {name: "Jan", age: 40};
// Remplir le tableau avec les clés de l'objet
const myArr = Object.keys(user); Modifier des objets
Une tâche typique de métaprogrammation consiste à modifier le comportement d'un objet :
Exemple
// Créer un objet
const person = {name: "John", age: 41};
// Définir "name" pour retourner "secret"
Object.defineProperty(person, "name", {
get() { return "secret"; }
});
let name = person.name; Générer du code dynamique
La métaprogrammation implique la génération de code dynamique.
JavaScript peut générer des fonctions à l'exécution :
Exemple
const fn = new Function("a", "b", "return a + b"); Exemples de métaprogrammation
| Concept | Description |
|---|---|
| Validation | Restreindre les valeurs pouvant être définies pour une propriété |
| Journalisation | Afficher les changements de propriété à l'aide d'un Proxy |
| Débogage | Intercepter une opération à l'aide d'un Proxy |
| Frameworks | Vue, MobX et Svelte utilisent la métaprogrammation pour détecter les changements d'état |
| ORM / mappage de base de données | Envelopper des objets et créer des champs en fonction du schéma de la base de données |
| APIs dynamiques | Créer des fonctions ou des structures d'objet à l'exécution |
Métaprogrammation Proxy
Les deux objets Proxy et Reflect permettent de programmer au niveau méta en JavaScript.
Proxy peut être utilisé pour intercepter des opérations sur les propriétés comme la lecture ou l'écriture.
Dans l'exemple ci-dessous :
- Un objet utilisateur est enveloppé dans un Proxy
- Le Proxy utilise un piège set() pour enregistrer chaque fois qu'une propriété est définie
Exemple
Enregistrer les changements des valeurs des propriétés :
// Créer un objet
const user = {name: "Jan", age: 40};
// Envelopper l'objet dans un Proxy
const proxy = new Proxy(user, {
// Utiliser un piège set
set(target, property, value) {
// Enregistrer les changements
log(property + "; " + value);
return target[property];
}
});
// Changer les propriétés
proxy.name = "John";
proxy.age = 45;
proxy.name = "Paul";
Proxy avec Reflect
Reflect fait correspondre le comportement de Proxy à celui des objets normaux
Dans l'exemple ci-dessous :
- Un objet utilisateur est enveloppé dans un Proxy
- Le Proxy utilise un piège set() pour enregistrer quand une propriété est définie
- Le piège set utilise Reflect.set() pour un transfert sécurisé
Exemple
Enregistrer les changements des valeurs des propriétés :
// Créer un objet
const user = {name: "Jan", age: 40};
// Envelopper l'objet dans un Proxy
const proxy = new Proxy(user, {
// Utiliser un piège set
set(target, property, value) {
// Enregistrer les changements
log(property + ": " + value);
// Transfert sécurisé avec Reflect
return Reflect.set(target, property, value);
}
});