Reflejar la introducción:
El objeto Reflect no se ha implementado en mi nodo (v4.4.3), y Babel (6.7.7) no se implementa. La nueva versión de Chrome es compatible. FF ha admitido proxy y reflexionado durante mucho tiempo. Si desea que Node admite reflexionar, puede instalar Harmony-Reflect;
Reflejar no es un constructor. Cuando se usa, se llama directamente a través de reflejo.method (). Algunos métodos de reflexión son similares al proxy, y la mayoría de los métodos reflejados se han vuelto a implementar objetos nativos.
Qué usar reflejar
Aquí hay algunas razones por las cuales se usa reflexión. Dirección de traducción: Reflexión, más o menos traducida:
1: Valor de retorno más útil: reflejar algunos métodos como el método de objeto en ES5, como: reflejar.getownpropertyDescriptor y reflej.defineProperty. Sin embargo, si el objeto. DefineProperty (OBJ, Nombre, Desc) se ejecuta con éxito, devolverá OBJ y otros errores causados por otras razones. Reflejar. DefineProperty solo devolverá falso o verdadero para indicar si se han establecido las propiedades del objeto. El siguiente código se puede refactorizar:
Pruebe {object.defineProperty (obj, nombre, descremo); // propiedad definida con éxito} capt (e) {// falla posible (y podría obtener accidentalmente la excepción incorrecta)}Reconstruido así:
if (reflejar.defineproperty (obj, name, desc)) {// éxito} else {// falla}Los otros métodos, como Relect.set, reflejan.deleteProperty, reflej.preventExtensions, reflej.setPrototypeOf, se pueden refactorizar;
2: operación de función. Si desea determinar que un OBJ tiene un nombre de atributo definido o hereda, puede juzgarlo en ES5 como este: Nombre en OBJ;
O eliminar un atributo: eliminar obj [nombre]. Aunque estos son muy útiles, muy cortos y claros, también deben estar encapsulados en una clase cuando se deben usar;
Con reflejar, te ayuda a encapsular, reflejar.
3: Método de ejecución funcional más confiable: en ES, si desea ejecutar una función F y pasar un conjunto de parámetros Args, y vincular esto, debe escribir esto:
F.Aply (obj, args)
Sin embargo, la aplicación F puede redefinirse como la propia aplicación del usuario, por lo que es más confiable escribir de esta manera:
Function.prototype.apply.call (F, obj, args)
El código anterior es demasiado largo y difícil de entender. Con reflexión, podemos ser más cortos y más concisos y claros:
Reflejar.apply (f, obj, args)
4: Constructores en forma de parámetro variádico: imagine que desea instanciar un constructor a través de parámetros de longitud incierta. En ES5, podemos usar símbolos de extensión, que se pueden escribir así:
var obj = nuevo f (... args)
Sin embargo, en ES5, los caracteres de extensión no son compatibles, por lo que solo podemos pasar diferentes parámetros en F.Aply o F.Call. Desafortunadamente, F es un constructor, que es una estafa, pero con reflejo,
Podemos escribir esto en ES5:
var obj = reflej.construct (f, args)
5: Esto controla el accesor o lector: en ES5, si desea leer los atributos de un elemento o establecer los atributos de la siguiente manera:
var name = ... // Obtener el nombre de la propiedad como StringObj [nombre] // Propiedad genérica LookUpobj [Nombre] = Valor // Propiedad genérica
Los métodos updaterReFlect.get y reflej.set nos permiten hacer lo mismo, y agrega un parámetro adicional al receptor, lo que nos permite establecer el setter del objeto y obtener y obtener esto:
var name = ... // Obtener el nombre de la propiedad como stringReflect.get (obj, nombre, wrapper) // Si obj [name] es un accesor, se ejecuta con `this === wrapper`reflect.set (obj, name, value, wrappers) El accesor no quiere usar su propio método, pero quiere redirigir esto a WRAPPER: var obj = {set foo (value) (value) }, bar: function () {alerta (1);}}; var wrapper = {bar: function () {console.log ("wrapper");}} reflej.set (obj, "foo", "valor", wrapper);6: Evite el acceso directo a __proto__:
ES5 proporciona Object.getPrototypeOf (OBJ) para acceder al prototipo del objeto, y ES6 proporciona también
Reflejar.getPrototypeOf (obj) y reflej.setPrototypeOf (OBJ, NewProto), este es un nuevo método para acceder y establecer el prototipo del objeto:
Reflejar el uso de la aplicación
Reflejar.apply es en realidad la función.prototype.apply () sustituye en ES5. Se requieren tres parámetros para ejecutar reflej. Aply.
El primer parámetro es: la función a ejecutar;
El segundo parámetro es: el contexto que debe ejecutarse;
El tercer parámetro es: es una matriz o pseudo-matriz, que se utilizará como un parámetro para ejecutar la función;
<script> let fn = functer () {this.attr = [0,1,2,3];}; vamos obj = {}; reflej.apply (fn, obj, []) console.log (obj); Demostración de <script> reflej.apply: <script> reflej.apply (math.floor, indefinido, [1.75]); // Salida: 1; reflej.apply (String.FromCharcode, Undefined, [104, 101, 108, 108, 111]); // Salida: "Hello" reflej.apply (regexp.prototype.exec,/ab/, ["confabulation"]). Index; // Salida: 4Reflect.Aply ("". Charat, "Ponies", [3]); // Salida: "I" </script> reflejar se puede usar en combinación con proxy: {var fn = function () {}; fn.prototype.run = function () {console.log ("rune out");}; var proxyfn = new proxy (fn, {construct (construct, arguments) {console.log ("nie Target (... argmentos); // cómo usar reflej.apply; reflej.apply (target.prototype.run, obj, aglomeración); return obj;}}); new proxyfn (); // La salida primero: "constructor proxy"; y luego salida: se agota} reflej.construct (): reflej.construct es en realidad un constructor de instanciación. Se implementa a través del formulario de argumento. El método de ejecución es diferente. El efecto es en realidad el mismo. El primer parámetro de construcción es el constructor, y el segundo parámetro es una matriz o una pseudo-array compuesta de parámetros. El método de uso básico es: var fn = function (arg) {this.args = [arg]}; console.log (nuevo fn (1), reflej.construct (fn, [1])); // La salida es la misma var d = reflej.construct (fecha, [1776, 6, 4]); d instancia de fecha; // true.getblyar (); // 1776 // SO reflexionar. El nuevo elemento heredará esta superclase; <script> function someconstructor () {} var result = reflej.construct (array, [], someconstructor); reflej.getPrototypeOf (resultado); // someconstructor.prototypearray.isArray (resultado); // true // orvar fn = function () {this.attr = [1];}; var persona = function () {}; persona.prototype.run = function () {}; console.log (reflej.construct (fn, [], persona)); </script> por lo que podemos usar esto para implementar una matriz especial, inheredura, pero también tenemos nuestros métodos; var fn = function () {array.apply (this, argumentos); this.shot = () => {console.log ("jeheda");};}; var arr = reflej.construct (fn, []) reflej.defineProperty; Reflejar. DefineProperty Devuelve un valor booleano, y el valor del atributo se agrega al objeto mediante asignación directa. Devuelve un objeto completo, si la adición falla, se lanzará un error; var obj = {}; obj.x = 10; console.log (obj.x) // output: 10; Agregar valor usando reflejar. DefineProperty; <script> var obj = {}; if (reflej.defineProperty (obj, "x", {valor: 7})) {console.log ("Se agregó éxito");} else {console.log ("Se agregó éxito");}; </script> Si ejecutamos preventextensions, informamos un error al definir la nueva propiedad. Reflejar.defineProperty, y se devuelve un valor falso: var obj = {}; object.preventExtensions (obj); object.defineProperty (obj, "x", {valor: 101, Writable: false, enumerable: falso, configurable: falso}); // Dirigido mal mal; console.log (reflejar.defineproperty (obj, "x", {valor: 101})) // return false: si el valor se asigna directamente, el valor establecido se devolverá independientemente de si el valor se asigna correctamente, a menos que confirmemos manualmente si el valor de la propiedad del objeto se establece con éxito; <script> var obj = {}; Object.PreventExtensions (obj); console.log (obj.aa = 1); // Salida: 1; console.log (obj.aa) // output: undefined; </script> reflej.deleteProperty Usage: reflej.deleteProperty y reflej.defineProperty Use es similar. Los resultados de la operación de reflejar. DeleteleProperty y Delete Obj.xx son los mismos. La diferencia es que los formularios de uso son diferentes: uno es un operador y el otro es una llamada de función; Reflejar.deleteProperty (Object.Freeze ({foo: 1}), "foo"); // falsedelete object.Freeze ({foo: 1}). foo; // Salida: falso; Hay dos parámetros necesarios para usar el método reflej.get (): el primero es el objeto de objetivo OBJ, el segundo es el objeto de nombre del atributo y el tercero es opcional, que es el contexto del lector (esto); var obj = {}; obj.foo = 1; console.log (obj.foo); // Salida: 1; console.log (reflejar.get (obj, "foo")) // salida: 1; si reflej.get tiene un tercer parámetro, el tercer parámetro se usará como el contexto del lector: var reflejar = request ('Harmony-Reflect'); var obj = {"foo": 1, get bar () {return this.foo;}}; var foo = {}; foo.foo = "jeheda"; console.log (reflej.get (obj, "bar", foo); reflej.getOwnpropertyDescriptor () Método: obtener el método de la propiedad a través de la descripción de la propiedad a través de la descripción de la propiedad. Reflej.getOwnPropertyDescriptor ({x: "Hola"}, "x"); // También puede obtenerlo así: Object.getOwnPropertyDescriptor ({x: "1"}, "x"); // La diferencia entre estos dos es que uno puede envolver el objeto, uno no: reflej.getOWNPROPERTYDESCRISTOR ("Hola", 0); // tirar una excepción objeto.getOwnPropertyDescriptor ("Hello", 0); // Salida: {valor: "H", Writitable: False, Enumerable: True, Configurable: False} reflej.getPrototypeOf () Métode Uso: reflej.getPrototypeOf y object.getPrototypeOf son los mismos, ambos devuelven el prototipo de un objeto. // salida: object.prototypeflect.getPrototypeOf (objeto.prototype); // Salida: NullReflect.getPrototypeOf (Object.Create (NULL)); // Salida: NullReflect.e el método de usar reflej.e es un poco como el operador: en, por ejemplo: xx en obj; <script> reflex.has ({x: 0}, "x") // output: true; Reflejar.has ({y: 0}, "y") // salida: true; var obj = {x: 0}; console.log ("x" en obj); var proxy = new Proxy (obj, {ha: function (target, args) {console.log ("ejecutar tiene método"); return reflej.has (target, ... args);}}); console.log ("x" en proxy); // Salida: True; console.log (reflej.has (proxy, "x")) // salida: true; </script> El obj de esta demostración es equivalente a convertirse en un método, es inútil, solo usa su método tiene: obj = nuevo proxy ({}, {ha (t, k) {return k.startswith ("puerta");}}); Reflejar.has (obj, "timbre"); // truereflect.has (obj, "dormitorio"); // falsereflect.isextensible () use // Ahora este elemento se puede extender; var vacía = {}; reflej.IsExtensible (vacía); // === true // use el método preventExtensions para evitar que este objeto extienda nuevos atributos; Reflejar.preventExtensions (vacío); Reflejar.IsExtensible (vacío); // === falso // Este objeto no puede extender nuevos atributos, y los atributos de escritura aún se pueden cambiar var sellado = object.seal ({}); reflej.isextensible (sellado); // === False // Este objeto está completamente congelado var Frozen = Object.Freeze ({}); reflejar.isextensible (Frozen); // === Falso La diferencia entre reflej.IsExtensible y Object.IsExtensible es que si el parámetro no es correcto, uno lanzará el incorrecto, y el otro simplemente devolverá verdadero o falso: reflej.isextensible (1); // lanza incorrecto: 1 no es un objeto. Reflejar el método del método reflejado (): reflej.ownkeys, el object no tiene el método OwnKeys, reflejado. console.log (reflej.ownkeys ({"a": 0, "b": 1, "c": 2, "d": 3})); // Salida: ["A", "B", "C", "D"] Console.log (reflejado.ownkeys ([])); // ["Longitud"] var symbol.for ("comet"); var sym2 = Symbol.for ("meteor"); var obj = {[sym]: 0, "str": 0, "773": 0, "0": 0, [sym2]: 0, "-1": 0, "8": 0, "segundo str": 0}; reflej.ownkeys (obj); // output: /["0", "8", "773", "str", "-1", "segundo str", símbolo (cometa), símbolo (meteor)] reflejes. Los keys se clasifican por: Primero muestran los números, los números están ordenados por tamaño, y luego las cadenas están ordenadas por el orden de la inscripción. Finalmente, las claves del tipo de símbolo también se clasifican de acuerdo con el orden de inserción; La clasificación ocurre porque cuando asigna un valor a un atributo de objeto, la regla de clasificación de la clave del objeto es al primer número, en una cadena y finalmente los datos del tipo de símbolo; El método de uso de reflej. Si el parámetro reflej.preventExtensions no es un objeto, lanzará un error; var vacía = {}; reflej.IsExtensible (vacía); // === true // El objeto después de ejecutar preventextensions puede modificarse; Reflejar.preventExtensions (vacío); Reflejar.IsExtensible (vacío); // === falsereflect.preventExtensions (1); // typeError: 1 no es un objectObject.preventExtensions (1); // No se lanza un error, se devolverá: 1Reflect.set () reflejar el método de set es similar a Get; var obj = {}; reflej.set (obj, "prop", "valor"); // Salida: TrueConsole.log (obj.prop); // Salida: "Valor" var arr = ["Duck", "Duck", "Duck"]; reflej.set (arr, 2, "Goose"); // trueConsole.log (arr [2]); // "Goose" reflej.set (arr, "longitud", 1); // trueConsole.log (arr); // ["duck"]; reflej.set (obj) es equivalente a reflejar.set (obj, indefinido, indefinido); var obj = {}; reflej.set (obj); // salida: true // El código anterior es equivalente a reflejar.set (obj, undefined, undefined); reflej.getownpropertyDescriptor (obj, "indefinido"); // {valor: undefined, witable: true, enumerable: true, configurable: true} reflej.set también puede tener un cuarto parámetro, que se utilizará como este de stter; var obj = {value 10, set. {console.log ("setter"); this.value = value;}, get key () {return this.value;}}; reflej.set (obj, "key", "jeheda", obj); console.log (obj); reflej.setPrototypeOf () reflej.setPrototypeOf () Method es similar al objeto. Establecerá un prototipo para el objeto, que es cambiar el atributo __proto__ del objeto ...; reflejar.setPrototipof ({}, objeto.prototype); // Salida True // a la matriz de objetos [[prototipo]] es null.reflect.setPrototypeOf ({}, null); // true // En este momento, obj .__ Proto__ está indefinido // libera el objeto y restablece [[prototipo]] reflej.setPrototipof (objeto.freeze ({}), null); // falso // Si la cadena prototipo depende del bucle, devolverá false.var Target = {}; var proto = object.create (target); reflej.setPrototypeOf (target, proto); // FALSO