HTML: Markup language
CSS: Styling language
JavaScript: Scripting language
Web APIs: Programming interfaces
All web technology
Learn web development
Discover our tools
Get to know MDN better
Esta página ha sido traducida del inglés por la comunidad. Aprende más y únete a la comunidad de MDN Web Docs.
View in English Always switch to English
A partir de ECMAScript 2015, JavaScript gana soporte para los objetos Proxy y Reflect lo cual te permite interceptar y definir un comportamiento personalizado para las operaciones fundamentales del lenguaje (por ejemplo, búsqueda de propiedades, asignación, enumeración, invocación de funciones, etc.). Con la ayuda de estos dos objetos, puedes programar en el metanivel de JavaScript.
Proxy
Reflect
Introducidos en ECMAScript 6, los objetos Proxy te permiten interceptar ciertas operaciones e implementar comportamientos personalizados.
Por ejemplo, obtener una propiedad sobre un objeto:
let handler = { get: function (target, name) { return name in target ? target[name] : 42; }, }; let p = new Proxy({}, handler); p.a = 1; console.log(p.a, p.b); // 1, 42
El objeto Proxy define un target (un objeto vacío aquí) y un objeto handler, en el que se implementa un get trap. Aquí, un objeto que es proxy no devolverá undefined cuando obtenga propiedades indefinidas, sino que devolverá el número 42.
target
handler
get
undefined
42
Hay ejemplos adicionales disponibles en la página de referencia Proxy.
Los siguientes términos se utilizan cuando se habla de la funcionalidad de los proxies.
Objeto marcador de posición que contiene trampas.
Los métodos que proporcionan acceso a la propiedad. (Esto es análogo al concepto de trampas en los sistemas operativos).
Objeto que virtualiza el proxy. A menudo se utiliza como interfaz de administración de almacenamiento para el proxy. Las invariantes (semántica que permanece sin cambios) con respecto a la no extensibilidad del objeto o las propiedades no configurables se verifican con el target.
La semántica que permanece sin cambios al implementar operaciones personalizadas se denominan invariants. Si violas las invariantes de un controlador, se lanzará un TypeError.
TypeError
La siguiente tabla resume las trampas disponibles para los objetos Proxy. Ve las páginas de referencia para explicaciones detalladas y ejemplos.
handler.getPrototypeOf()
Object.getPrototypeOf()
Reflect.getPrototypeOf()
__proto__
Object.prototype.isPrototypeOf()
instanceof
getPrototypeOf
null
Object.getPrototypeOf(proxy)
Object.getPrototypeOf(target)
handler.setPrototypeOf()
Object.setPrototypeOf()
Reflect.setPrototypeOf()
prototype
handler.isExtensible()
Object.isExtensible()
Reflect.isExtensible()
Object.isExtensible(proxy)
Object.isExtensible(target)
handler.preventExtensions()
Object.preventExtensions()
Reflect.preventExtensions()
Object.preventExtensions(proxy)
true
false
handler.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor()
getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor(target)
Object.defineProperty
handler.defineProperty()
Object.defineProperty()
Reflect.defineProperty()
Object.defineProperty(target, prop, descriptor)
defineProperty
handler.has()
foo in proxy
foo in Object.create(proxy)
Reflect.has()
handler.get()
proxy[foo]
proxy.bar
Object.create[proxy](foo)
Reflect.get()
[[Get]]
handler.set()
proxy[foo] = bar
proxy.foo = bar
Object.create[proxy](foo) = bar
set
handler.deleteProperty()
delete proxy[foo]
delete proxy.foo
Reflect.deleteProperty()
handler.enumerate()
for...in
for (let name in proxy) {...}
Reflect.enumerate()
enumerate
handler.ownKeys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
ownKeys
String
Symbol
handler.apply()
proxy(..args)
Function.prototype.apply()
Function.prototype.call()
Reflect.apply()
handler.apply
handler.construct()
new proxy(...args)
Reflect.construct()
Objeto
El método Proxy.revocable() se usa para crear un objeto Proxy revocable. Esto significa que el proxy se puede revocar mediante la función revoke y apagar el proxy.
Proxy.revocable()
revoke
Posteriormente, cualquier operación en el proxy conduce a un TypeError.
let revocable = Proxy.revocable( {}, { get: function (target, name) { return "[[" + name + "]]"; }, }, ); let proxy = revocable.proxy; console.log(proxy.foo); // "[[foo]]" revocable.revoke(); console.log(proxy.foo); // Lanza TypeError proxy.foo = 1; // TypeError nuevamente delete proxy.foo; // todavía TypeError typeof proxy; // "object", typeof no activa ninguna trampa
Reflect es un objeto integrado que proporciona métodos para operaciones JavaScript interceptables. Los métodos son los mismos que los de proxy handlers.
Reflect no es un objeto función.
Reflect ayuda con el reenvío de las operaciones predeterminadas del controlador al target.
Con Reflect.has() por ejemplo, obtienes el operador in como función:
in
Reflect.has(Object, "assign"); // true
apply
En ES5, normalmente usas el método Function.prototype.apply() para llamar a una función con un valor this y arguments proporcionado como un arreglo (o un objeto similar a un arreglo).
this
arguments
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
Con Reflect.apply esto se vuelve menos detallado y más fácil de entender:
Reflect.apply
Reflect.apply(Math.floor, undefined, [1.75]); // 1; Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]); // "hola" Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index; // 4 Reflect.apply("".charAt, "ponies", [3]); // "i"
Con Object.defineProperty, que devuelve un objeto si tiene éxito, o arroja un TypeError de lo contrario, usaría un bloque try...catch para detectar cualquier error que haya ocurrido al definir una propiedad. Debido a que Reflect.defineProperty devuelve un estado de éxito booleano, aquí puedes usar un bloque if...else:
try...catch
Reflect.defineProperty
if...else
if (Reflect.defineProperty(target, property, attributes)) { // éxito } else { // fracaso }