From 844f5103992238c0c23203286dad16a466e89c97 Mon Sep 17 00:00:00 2001 From: julieng Date: Tue, 3 Aug 2021 08:03:09 +0200 Subject: move *.html to *.md --- .../reference/global_objects/proxy/index.html | 406 --------------------- 1 file changed, 406 deletions(-) delete mode 100644 files/fr/web/javascript/reference/global_objects/proxy/index.html (limited to 'files/fr/web/javascript/reference/global_objects/proxy/index.html') diff --git a/files/fr/web/javascript/reference/global_objects/proxy/index.html b/files/fr/web/javascript/reference/global_objects/proxy/index.html deleted file mode 100644 index d02e303881..0000000000 --- a/files/fr/web/javascript/reference/global_objects/proxy/index.html +++ /dev/null @@ -1,406 +0,0 @@ ---- -title: Proxy -slug: Web/JavaScript/Reference/Global_Objects/Proxy -tags: - - ECMAScript 2015 - - JavaScript - - Proxy - - Reference -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy -original_slug: Web/JavaScript/Reference/Objets_globaux/Proxy ---- -
{{JSRef}}
- -

L'objet Proxy est utilisé afin de définir un comportement sur mesure pour certaines opérations fondamentales (par exemple, l'accès aux propriétés, les affectations, les énumérations, les appels de fonctions, etc.).

- -

Terminologie

- -
-
gestionnaire (handler)
-
Un objet qui contient les trappes qui intercepteront les opérations.
-
trappes
-
Les méthodes qui fournissent l'accès aux propriétés. Ce concept est analogue aux trappes utilisées dans les systèmes d'exploitations.
-
cible
-
L'objet virtualisé par le proxy. Il est souvent utilisé comme objet de stockage. Les invariants (c'est-à-dire les éléments de sémantique qui restent inchangés) relatifs à la non-extensibilité et au caractère non-configurable des propriétés sont vérifiés par rapport à la cible.
-
- -

Syntaxe

- -
var p = new Proxy(cible, gestionnaire);
-
- -

Paramètres

- -
-
cible
-
Une cible (qui peut être n'importe quel objet, un tableau, une fonction, ou même un autre proxy) qu'on souhaite envelopper dans un Proxy.
-
gestionnaire
-
Un objet dont les propriétés sont des fonctions qui définissent le comportement du proxy lorsqu'on utilise une opération sur celui-ci.
-
- -

Méthodes

- -
-
{{jsxref("Proxy.revocable()")}}
-
Permet de créer un objet Proxy révocable.
-
- -

Méthodes pour le gestionnaire

- -

L'objet utilisé comme gestionnaire regroupe les différentes fonctions « trappes » pour le Proxy.

- -
{{page('/fr/docs/Web/JavaScript/Reference/Objets_globaux/Proxy/handler', 'Méthodes') }}
- -

Exemples

- -

Exemple simple

- -

Dans ce court exemple, on renvoie le nombre 37 comme valeur par défaut lorsque la propriété nommée n'est pas présente dans l'objet. Pour cela, on utilise le gestionnaire correspondant à {{jsxref("Objets_globaux/Proxy/handler/get","get")}}.

- -
var handler = {
-    get: function(obj, prop){
-        return prop in obj?
-            obj[prop] :
-            37;
-    }
-};
-
-var p = new Proxy({}, handler);
-p.a = 1;
-p.b = undefined;
-
-console.log(p.a, p.b); // 1, undefined
-console.log('c' in p, p.c); // false, 37
-
- -

Proxy « invisible »

- -

Dans cet exemple, le proxy transfère toutes les opérations qui sont appliquées à l'objet cible.

- -
var cible = {};
-var p = new Proxy(cible, {});
-
-p.a = 37; // L'opération est transmise à la cible par le proxy
-
-console.log(cible.a); // 37. L'opération a bien été transmise
-
- -

Validation

- -

En utilisant un Proxy, il devient simple de valider les valeurs passées à un objet. Dans cet exemple, on utilise le gestionnaire correspondant à {{jsxref("Objets_globaux/Proxy/handler/set","set")}}.

- -
let validateur = {
-  set: function(obj, prop, valeur) {
-    if (prop === 'âge') {
-      if (!Number.isInteger(valeur)) {
-        throw new TypeError('Cet âge n\'est pas un entier.');
-      }
-      if (valeur > 200) {
-        throw new RangeError('Cet âge semble invalide.');
-      }
-    }
-
-    // Le comportement par défaut : enregistrer la valeur
-    obj[prop] = valeur;
-
-    // On indique le succès de l'opération
-    return true;
-  }
-};
-
-let personne = new Proxy({}, validateur);
-
-personne.âge = 100;
-console.log(personne.âge); // 100
-personne.âge = 'jeune';    // lève une exception
-personne.âge = 300;        // lève une exception
-
- -

Étendre un constructeur

- -

En utilisant une fonction proxy, on peut étendre un constructeur avec un nouveau constructeur. Dans cet exemple, on utilise les gestionnaires correspondants à {{jsxref("Objets_globaux/Proxy/handler/construct","construct")}} et {{jsxref("Objets_globaux/Proxy/handler/apply","apply")}}.

- -
function étendre(sup,base) {
-  var descripteur = Object.getOwnPropertyDescriptor(
-    base.prototype, "constructor"
-  );
-  base.prototype = Object.create(sup.prototype);
-  var gestionnaire = {
-    construct: function(cible, args) {
-      var obj = Object.create(base.prototype);
-      this.apply(cible,obj,args);
-      return obj;
-    },
-    apply: function(cible, that, args) {
-      sup.apply(that,args);
-      base.apply(that,args);
-    }
-  };
-  var proxy = new Proxy(base,gestionnaire);
-  descripteur.value = proxy;
-  Object.defineProperty(base.prototype, "constructor", descripteur);
-  return proxy;
-}
-
-var Personne = function(nom){
-  this.nom = nom;
-};
-
-var Garçon = étendre(Personne, function(nom, âge) {
-  this.âge = âge;
-});
-
-Garçon.prototype.genre = "M";
-
-var Pierre = new Garçon("Pierre", 13);
-console.log(Pierre.genre);  // "M"
-console.log(Pierre.nom);  // "Pierre"
-console.log(Pierre.âge);  // 13
- -

Manipuler les nœuds DOM

- -

Parfois, on veut passer un attribut ou un nom de classe entre deux éléments différents. Dans cet exemple, on utilise le gestionnaire lié à {{jsxref("Objets_globaux/Proxy/handler/set","set")}}.

- -
let vue = new Proxy({
-  selected: null
-},
-{
-  set: function(obj, prop, nouvelleValeur) {
-    let ancienneValeur = obj[prop];
-
-    if (prop === 'selected') {
-      if (ancienneValeur) {
-        ancienneValeur.setAttribute('aria-selected', 'false');
-      }
-      if (nouvelleValeur) {
-        nouvelleValeur.setAttribute('aria-selected', 'true');
-      }
-    }
-
-    // Le comportement par défaut : enregistrer la valeur
-    obj[prop] = nouvelleValeur;
-
-    // On indique le succès de l'opération
-    return true;
-  }
-});
-
-let i1 = vue.selected = document.getElementById('item-1');
-console.log(i1.getAttribute('aria-selected')); // 'true'
-
-let i2 = vue.selected = document.getElementById('item-2');
-console.log(i1.getAttribute('aria-selected')); // 'false'
-console.log(i2.getAttribute('aria-selected')); // 'true'
-
- -

Corriger une valeur et ajouter une propriété supplémentaire

- -

Dans l'exemple qui suit, le proxy produits évalue la valeur passée et la convertit en tableau si besoin. L'objet supporte également la propriété supplémentaire dernierNavigateur à la fois comme accesseur et mutateur.

- -
let produits = new Proxy({
-  navigateurs: ['Internet Explorer', 'Netscape']
-},
-{
-  get: function(obj, prop) {
-    // Une propriété supplémentaire
-    if (prop === 'dernierNavigateur') {
-      return obj.navigateurs[obj.navigateurs.length - 1];
-    }
-
-    // Le comportement par défaut : renvoyer la valeur
-    return obj[prop];
-  },
-  set: function(obj, prop, valeur) {
-    // Une propriété supplémentaire
-    if (prop === 'dernierNavigateur') {
-      obj.navigateurs.push(valeur);
-      return true;
-    }
-
-    // on convertit la valeur si ce n'est pas un tableau
-    if (typeof valeur === 'string') {
-      valeur = [valeur];
-    }
-
-    // Le comportement par défaut : enregistrer la valeur
-    obj[prop] = valeur;
-
-    // On indique le succès de l'opération
-    return true;
-  }
-});
-
-console.log(produits.navigateurs); // ['Internet Explorer', 'Netscape']
-produits.navigateurs = 'Firefox'; // on passe une chaîne
-console.log(produits.navigateurs); // ['Firefox'] <- pas de problème, elle est convertie en tableau
-
-produits.dernierNavigateur = 'Chrome';
-console.log(produits.navigateurs); // ['Firefox', 'Chrome']
-console.log(produits.dernierNavigateur); // 'Chrome'
-
- -

Trouver un élément dans un tableau grâce à sa propriété

- -

Dans cet exemple, ce proxy étend le tableau avec des fonctionnalités supplémentaires. Ici, on définit des propriétés sans utiliser {{jsxref("Objets_globaux/Object/defineProperties","Object.defineProperties")}}. Cet exemple pourrait être adapté pour trouver la ligne d'un tableau à partir d'une de ces cellules (la cible serait alors table.rows).

- -
let produits = new Proxy([
-  { nom: 'Firefox', type: 'navigateur' },
-  { nom: 'SeaMonkey', type: 'navigateur' },
-  { nom: 'Thunderbird', type: 'client mail' }
-],
-{
-  get: function(obj, prop) {
-    // Le comportement par défaut : on renvoie la valeur
-    // prop est généralement un entier
-    if (prop in obj) {
-      return obj[prop];
-    }
-
-    // On obtient le nombre de produits
-    // un alias pour products.length
-    if (prop === 'nombre') {
-      return obj.length;
-    }
-
-    let résultat, types = {};
-
-    for (let produit of obj) {
-      if (produit.nom === prop) {
-        résultat = produit;
-      }
-      if (types[produit.type]) {
-        types[produit.type].push(produit);
-      } else {
-        types[produit.type] = [produit];
-      }
-    }
-
-    // Obtenir un produit grâce à un nom
-    if (résultat) {
-      return résultat;
-    }
-
-    // Obtenir un produit par type
-    if (prop in types) {
-      return types[prop];
-    }
-
-    // Obtenir les types de produits
-    if (prop === 'types') {
-      return Object.keys(types);
-    }
-
-    return undefined;
-  }
-});
-
-console.log(produits[0]); // { nom: 'Firefox', type: 'navigateur' }
-console.log(produits['Firefox']); // { nom: 'Firefox', type: 'navigateur' }
-console.log(produits['Chrome']); // undefined
-console.log(produits.navigateur); // [{ nom: 'Firefox', type: 'navigateur' }, { nom: 'SeaMonkey', type: 'navigateur' }]
-console.log(produits.types); // ['navigateur', 'client mail']
-console.log(produits.nombre); // 3
-
- -

Un exemple avec toutes les trappes

- -

Pour illustrer l'ensemble des trappes, on tente de « proxifier » un objet non natif : l'objet global docCookies créé grâce à cet exemple.

- -
/*
-  var docCookies = ... définir l'objet "docCookies" grâce à
-  https://developer.mozilla.org/en-US/docs/DOM/document.cookie#A_little_framework.3A_a_complete_cookies_reader.2Fwriter_with_full_unicode_support
-*/
-
-var docCookies = new Proxy(docCookies, {
-  "get": function (oTarget, sKey) {
-    return oTarget[sKey] || oTarget.getItem(sKey) || undefined;
-  },
-  "set": function (oTarget, sKey, vValue) {
-    if (sKey in oTarget) { return false; }
-    return oTarget.setItem(sKey, vValue);
-  },
-  "deleteProperty": function (oTarget, sKey) {
-    if (sKey in oTarget) { return false; }
-    return oTarget.removeItem(sKey);
-  },
-  "enumerate": function (oTarget, sKey) {
-    return oTarget.keys();
-  },
-  "ownKeys": function (oTarget, sKey) {
-    return oTarget.keys();
-  },
-  "has": function (oTarget, sKey) {
-    return sKey in oTarget || oTarget.hasItem(sKey);
-  },
-  "defineProperty": function (oTarget, sKey, oDesc) {
-    if (oDesc && "value" in oDesc) { oTarget.setItem(sKey, oDesc.value); }
-    return oTarget;
-  },
-  "getOwnPropertyDescriptor": function (oTarget, sKey) {
-    var vValue = oTarget.getItem(sKey);
-    return vValue ? {
-      "value": vValue,
-      "writable": true,
-      "enumerable": true,
-      "configurable": false
-    } : undefined;
-  },
-});
-
-/* Cookies test */
-
-console.log(docCookies.mon_cookie1 = "Première valeur");
-console.log(docCookies.getItem("mon_cookie1"));
-
-docCookies.setItem("mon_cookie1", "Valeur modifiée");
-console.log(docCookies.mon_cookie1);
- -

Spécifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpécificationÉtatCommentaires
{{SpecName('ES2015', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ES2015')}}Définition initiale.
{{SpecName('ES2016', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ES2016')}}
{{SpecName('ES2017', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-proxy-objects', 'Proxy')}}{{Spec2('ESDraft')}}
- -

Compatibilité des navigateurs

- -

{{Compat("javascript.builtins.Proxy", 2)}}

- -

Voir aussi

- - - -

Notes de licence

- -

Certains composants de cette page (texte, exemples) ont été copiés ou adaptés du Wiki ECMAScript dont le contenu est sous licence CC 2.0 BY-NC-SA.

-- cgit v1.2.3-54-g00ecf