Refléter l'introduction:
L'objet de réflexion n'a pas été mis en œuvre dans mon nœud (v4.4.3), et Babel (6.7.7) n'est pas implémenté. La nouvelle version de Chrome est prise en charge. FF a pris en charge le proxy et réfléchit depuis longtemps. Si vous voulez que le nœud prenne en charge la réflexion, vous pouvez installer Harmony-reflect;
La réflexion n'est pas un constructeur. Lorsqu'il est utilisé, il est appelé directement via Reflect.Method (). Certaines méthodes de réflexion sont similaires à la proxy, et la plupart des méthodes reflètent les méthodes que les objets natifs ont été réimplémentés.
Quoi utiliser reflète
Voici quelques raisons pour lesquelles la réflexion est utilisée. Adresse de traduction: réfléchir, grossièrement traduit:
1: Valeur de retour plus utile: Reflect a certaines méthodes comme la méthode de l'objet dans ES5, telles que: Reflect.GetownProperTyDescriptor et Reflect.DefineProperty. Cependant, si l'objet.defineproperty (obj, nom, desc) est exécuté avec succès, il renverra OBJ et d'autres erreurs causées par d'autres raisons. Reflect.DefineProperty ne rendra que False ou True pour indiquer si les propriétés de l'objet ont été définies. Le code suivant peut être refactorisé:
essayez {object.defineProperty (obj, nom, desc); // propriété définie avec succès} catch (e) {// défaillance possible (et pourrait accidentellement attraper la mauvaise exception)}Reconstruit comme ceci:
if (Reflect.defineProperty (obj, nom, desc)) {// succès} else {// défaillance}Les autres méthodes, telles que relect.set, reflète.
2: fonctionnement de la fonction. Si vous voulez déterminer qu'un OBJ a un ou hérite défini ou hérite du nom d'attribut, vous pouvez le juger dans ES5 comme ceci: nom dans OBJ;
Ou supprimer un attribut: supprimer obj [nom]. Bien que ceux-ci soient très utiles, très courts et clairs, ils doivent également être encapsulés dans une classe lorsqu'ils doivent être utilisés;
Avec Reflect, il vous aide à encapsuler, refléter.
3: Méthode d'exécution fonctionnelle plus fiable: Dans ES, si vous souhaitez exécuter une fonction F et transmettre un ensemble de paramètres d'args, et le lier, vous devez écrire ceci:
F.Apply (obj, args)
Cependant, l'application F peut être redéfinie comme la propre application de l'utilisateur, il est donc plus fiable d'écrire de cette façon:
Function.prototype.apply.Call (F, Obj, Args)
Le code ci-dessus est trop long et difficile à comprendre. Avec réflexion, nous pouvons être plus courts et plus concis et plus clairs:
Reflect.Apply (F, OBJ, Args)
4: Constructeurs sous forme de paramètres variades: Imaginez que vous souhaitez instancier un constructeur à travers des paramètres de longueur incertaine. Dans ES5, nous pouvons utiliser des symboles d'extension, qui peuvent être écrits comme ceci:
var obj = new f (... args)
Cependant, dans ES5, les caractères d'extension ne sont pas pris en charge, nous ne pouvons donc transmettre que différents paramètres dans F.Apply ou F.Call. Malheureusement, F est un constructeur, qui est une arnaque, mais avec réfléchir,
Nous pouvons écrire ceci dans ES5:
var obj = réflect.construct (f, args)
5: Cela contrôle l'accessoire ou le lecteur: dans ES5, si vous souhaitez lire les attributs d'un élément ou définir les attributs comme suit:
var name = ... // Obtenez le nom de la propriété en tant que stringoBj [name] // propriété générique lookupObj [name] = valeur // propriété générique
Les méthodes UpdateReflect.get et Reflect.Set nous permettent de faire la même chose, et il ajoute un paramètre supplémentaire au recciver, nous permettant de définir le secteur et le getter de l'objet de haut en bas:
var name = ... // Obtenez le nom de la propriété en tant que stringReflect.get (obj, nom, wrapper) // Si obj [name] est un accessoire, il est exécuté avec `this === wrapper`reflect.set (obj, nom, valeur, wrapper) L'accesseur ne veut pas utiliser sa propre méthode, mais souhaite rediriger ce.bar (); }, bar: function () {alert (1);}}; var wrapper = {bar: function () {console.log ("wrapper");}} reflev.set (obj, "foo", "valeur", wrapper);6: Évitez l'accès direct à __proto__:
ES5 fournit objet.getPrototypeOf (OBJ) pour accéder au prototype de l'objet, et ES6 fournit également
Reflect.getPrototypeOf (OBJ) et Reflect.setprototypeOf (OBJ, newproto), il s'agit d'une nouvelle méthode pour accéder et définir le prototype de l'objet:
Réfléchissez.Apply Utilisation
Reflect.Apply est en fait la fonction.prototype.apply () substitut dans ES5. Trois paramètres sont nécessaires pour exécuter la réflexion.
Le premier paramètre est: la fonction à exécuter;
Le deuxième paramètre est: le contexte qui doit être exécuté;
Le troisième paramètre est: est un tableau ou un pseudo-argent, qui sera utilisé comme paramètre pour exécuter la fonction;
<Script> Soit fn = function () {this.attr = [0,1,2,3];}; let obj = {}; reflète.apply (fn, obj, []) console.log (obj); Démo de <Script> reflète.apply: <cript> reflète.apply (math.floor, undefined, [1.75]); // Sortie: 1; Reflect.Apply (String.fromCharcode, Undefined, [104, 101, 108, 108, 111]); // sortie: "bonjour" reflète.apply (regexp.prototype.exec, / ab /, ["confabulation"]). Index; // sortie: 4Reflect.Apply ("". Charat, "Ponies", [3]); // Sortie: "i" </cript> Réfléchir peut être utilisé en combinaison avec proxy: {var fn = function () {}; fn.prototype.run = function () {console.log ("renut");}; var proxyfn = new proxy (fn, {construction (cible, arugments) {console.log ("proxy"); var Ob = VarO = VARB = VAR = Target (... Arugments); // comment utiliser Reflect.Apply; Reflect.Apply (cible.prototype.run, obj, arugments); return obj;}}); new proxyfn (); // la sortie d'abord: "Constructeur proxy"; puis la sortie: épreuse} reflète.Construct (): Reflect.Construct est en fait un constructeur d'instanciation. Il est implémenté par le formulaire d'argument. La méthode d'exécution est différente. L'effet est en fait le même. Le premier paramètre de construction est le constructeur, et le deuxième paramètre est un tableau ou un pseudo-arrié composé de paramètres. La méthode d'utilisation de base est: var fn = fonction (arg) {this.args = [arg]}; console.log (new fn (1), réflect.construct (fn, [1])); // La sortie est la même var d = réflect.construct (Date, [1776, 6, 4]); d instanceof date; // trued.getlyar (); // 1776 // ainsi réfléchir et la nouvelle construction, donc la construction et la nouvelle construction sont les mêmes, au moins jusqu'à présent ... nous pouvons passer le troisième paramètre pour refléter.Construct, et le troisième paramètre est une superclasse. Le nouvel élément héritera de cette superclasse; <Script> Fonction Someconstructor () {} var result = refleft.Construct (array, [], Someconstructor); refleft.getPrototypeOf (result); // Someconstructor.prototypeArray.isArray (résultat); // true // orvar fn = function () {this.attr = [1];}; var person = function () {}; personne.prototype.run = function () {}; console.log (reflevant.construct (fn, [], personne)); </cript> afin que nous puissions utiliser cela pour mettre en œuvre un tableau spécial, inhérent le tableau, mais nous avons également nos propres méthodes; var fn = function () {array.Apply (this, arguments); this.shot = () => {console.log ("heheda");};}; var arr = réflect.construct (fn, []) reflète.defineproperty; Reflect.DefineProperty renvoie une valeur booléenne et la valeur d'attribut est ajoutée à l'objet par affectation directe. Renvoie un objet entier, si l'ajout échoue, une erreur sera lancée; var obj = {}; obj.x = 10; console.log (obj.x) // sortie: 10; Ajouter de la valeur à l'aide de réflect.defineProperty; <script> var obj = {}; if (reflev.defineproperty (obj, "x", {value: 7})) {console.log ("succès ajouté");} else {console.log ("Ajout de succès");}; </ script> Si nous exécutons la prévention, nous signalons une erreur en définissant le nouveau propriété par objet.DefindProperty, nous rapportons une erreur en définissant la nouvelle propriété. Reflect.defineProperty, et une fausse valeur est renvoyée: var obj = {}; object.preventextensions (obj); object.defineproperty (obj, "x", {value: 101, écrivable: false, énumérable: false, configurable: false}); // directement épuisé; Console.log (reflète.defineProperty (obj, "x", {valeur: 101})) // return false: Si la valeur est directement attribuée, la valeur définie sera renvoyée, que la valeur soit attribuée correctement, sauf si nous confirmons manuellement si la valeur de propriété de l'objet est définie avec succès; <script> var obj = {}; object.preventextensions (obj); console.log (obj.aa = 1); // Sortie: 1; Console.log (OBJ.AA) // Sortie: Undefined; </cript> Reflect. Les résultats de l'opération de Reflect.Deleteproperty et Supprimer Obj.xx sont les mêmes. La différence est que les formulaires d'utilisation sont différents: l'un est un opérateur et l'autre est un appel de fonction; Reflect.DeleTeproperty (object.freeze ({foo: 1}), "foo"); // falSedelete object.freeze ({foo: 1}). foo; // sortie: false; Il existe deux paramètres nécessaires pour utiliser la méthode Reflect.get (): le premier est l'objet cible OBJ, le second est l'objet de nom d'attribut, et le troisième est facultatif, qui est le contexte du lecteur (this); var obj = {}; obj.foo = 1; console.log (obj.foo); // Output: 1; console.log (Reflect.get (obj, "foo")) // output: 1; if Reflect.get a un troisième paramètre, le troisième paramètre sera utilisé comme contexte du lecteur: var reflect = require ('harmonie-reflect'); var obj = {"foo": 1, get bar () {return this.foo;}}; var foo = {}; foo.foo = "heheda"; console.log (reflev.get (obj, "bar", foo)); releft.getownpropertyDescriptor () Méthode: Get the Property Description. Reflect.getownProperTyDescriptor ({x: "Hello"}, "x"); // Vous pouvez également l'obtenir comme ceci: object.getownpropertyDescriptor ({x: "1"}, "x"); // la différence entre ces deux est que l'on peut envelopper l'objet, on ne fait pas: réflect.getownpropertyDescriptor ("bonjour", 0); // lance une exception objet.getownpropertyDescriptor ("Hello", 0); // output: {valeur: "h", écrivable: false, énumérable: true, configurable: false} reflète.getprototypeof () Utilisation de la méthode: reflect.getprototypeof et object.getprototypeof sont les mêmes, ils renvoient tous les deux le prototype d'un objet Reflect.getPrototypeOf ({}); // output: object.prototypeReflect.getPrototypeOf (object.prototype); // sortie: nullReflect.getPrototypeOf (object.create (null)); // output: nullReflect.has la méthode d'utilisation de réflect. Reflect.has ({y: 0}, "y") // output: true; var obj = {x: 0}; console.log ("x" dans obj); var proxy = new proxy (obj, {has: function (cible, args) {console.log ("Execute a méthode"); return réflect.has (cible, ... args);}}); console.log ("x" dans proxy); // sortie: vrai; Console.log (reflète.has (proxy, "x")) // output: true; </ script> L'OBJ de cette démo équivaut à devenir une méthode, il est inutile, il utilise simplement sa méthode a: obj = nouveau proxy ({}, {a (t, k) {return k.startswith ("porte");}}); Refléter.has (obj, "sonnette"); // truereflect.has (obj, "dortory"); // falsereflect.isextenible () use // maintenant cet élément peut être étendu; var vide = {}; réflect.isextenible (vide); // === true // Utiliser la méthode de prévention pour empêcher cet objet d'étendre les nouveaux attributs; Reflect.pretentextensions (vide); Réflect.isextenible (vide); // === false // Cet objet ne peut pas étendre de nouveaux attributs, et les attributs écrivables peuvent toujours être modifiés var scelled = object.seal ({}); reflev.isextenible (scellé); // === false // Cet objet est complètement figé var geène = object.freeze ({}); reflev.isextenible (gelen); // === FAUX La différence entre réflect.isextenible et object.isextenible est que si le paramètre n'est pas correct, l'un lancera le mauvais, et l'autre reviendra vrai ou false: réflect.isextenible (1); // mauvais throw: 1 n'est pas objectObject.isextenible (1); // return false; Reflect.ownKeys () Méthode Utilisation: Reflect.ownKeys, l'objet n'a pas la méthode Ownkeys, reflète. console.log (reflev.ownkeys ({"a": 0, "b": 1, "c": 2, "d": 3})); // sortie: ["A", "B", "C", "D"] Console.log (Reflect.OwnKeys ([])); // ["longueur"] var sym = symbol.for ("comète"); var sym2 = symbol.for ("Meteor"); var obj = {[sym]: 0, "str": 0, "773": 0, "0": 0, [sym2]: 0, "-1": 0, "8": 0, "second str": 0}; reflev.ownkeys (obj); // output: / ["0", "8", "773", "str", "-1", "deuxième str", symbole (comète), symbole (météor)] reflect.Ownkeys est trié par: d'abord afficher les nombres, les nombres sont triés par taille, puis les chaînes sont triées par ordre d'insertion. Enfin, les clés du type de symbole sont également triées en fonction de l'ordre d'insertion; Le tri se produit parce que lorsque vous attribuez une valeur à un attribut d'objet, la règle de tri de la clé d'objet est de premier numéro, dans une chaîne, et enfin les données du type de symbole; La méthode d'utilisation de Reflect.PretenExtensions (): l'objet a également une méthode de préventive, qui est un peu différente de Reflect.PretenExtensions (). Si le paramètre Reflect.Pretentextensions n'est pas un objet, il lancera une erreur; var vide = {}; réflect.isextenible (vide); // === true // L'objet après l'exécution de prévenus peut être modifié; Reflect.pretentextensions (vide); Réflect.isextenible (vide); // === falseReflect.Preventextensions (1); // typeError: 1 n'est pas un objetObject.PretenExtensions (1); // aucune erreur n'est lancée, il reviendra: 1Reflect.set () réflect.set La méthode est similaire à obtenir; var obj = {}; réflect.set (obj, "prop", "valeur"); // sortie: trueconsole.log (obj.prop); // sortie: "valeur" var arr = ["Duck", "Duck", "Duck"]; réflect.set (arr, 2, "Goose"); // trueconsole.log (arr [2]); // "goose" reflète.set (arr, "longueur", 1); // trueconsole.log (arr); // ["Duck"]; reflète.set (obj) est équivalent à réflexion.set (obj, non défini, non défini); var obj = {}; réflect.set (obj); // Sortie: Vrai // Le code ci-dessus est équivalent à Reflect.set (obj, undefined, undefined); Reflect.getownPropertyDescriptor (obj, "Undefined"); // {valeur: Undefined, Writable: True, énuable: True, configurable: True} reflect.set peut également avoir un quatre dernier paramètre, qui sera utilisé {console.log ("setter"); this.value = value;}, get key () {return this.value;}}; reflev.set (obj, "key", "heheda", obj); console.log (obj); reflev.set.setprototypeof () reflev.setprotypeof () méthode est similaire à l'objet.setpototypeof. Il définira un prototype pour l'objet, qui consiste à modifier l'attribut __proto__ de l'objet ...; reflète.setprototypeof ({}, objet.prototype); // output true // au tableau d'objets [[prototype]] est null.reflect.setprototypeof ({}, null); // true // À l'heure actuelle, obj .__ proto__ est indéfini // libre de l'objet et réinitialisation [[prototype]] reflev.setprototypeof (object.freeze ({}), null); // false // Si la chaîne prototype dépend de la boucle, elle renverra false.var cible = {}; var proto = object.create (cible); reflev.setPrototypeOf (cible, proto); // FAUX