Los objetos Proxy son un tipo de objeto nativo que fue introducido en la versión ES2015 de JavaScript y que sirve para observar cambios en cualquier otro objeto. Cuando se intercepte un cambio, será posible ejecutar automáticamente cualquier función definida.
Introducción a los objetos Proxy
Antes de declarar un objeto Proxy, vamos a declarar cualquier otro objeto para así ver su funcionamiento. Por ejemplo, vamos a declarar el objeto persona
:
const persona = {
nombre: 'Edu',
apellido: 'Lazaro'
}
Lo que vamos a hacer es crear una función que nos devuelva el texto 'Propiedad no encontrada'
cada vez que intentemos acceder a una propiedad del objeto que no exista. Para ello vamos a valernos de un proxy al que llamaremos cada vez que intentemos acceder a una propiedad del objeto.
Vamos a crear un método get()
que reciba tanto el objeto como la propiedad como parámetros:
const persona = {
nombre: 'Edu',
apellido: 'Lazaro'
}
const handler = {
get(objeto, prop) {
return objeto[prop] ?? 'Propiedad no encontrada';
}
}
A continuación vamos a crear nuestro proxy usando la función new Proxy()
, a la que pasaremos tanto el objeto que queremos observar como la lista de posibles tareas, entre las cuales está nuestra tarea get()
:
const proxyPersona = new Proxy(persona, handler);
Ahora vamos a intentar acceder a cualquier propiedad del objeto persona
pero haciendo referencia a él desde nuestro proxy proxyPersona
:
const nombre = proxyPersona.nombre;
console.log(nombre); // 'Edu'
Tal y como puedes ver, ocurre lo mismo que si hubieses accedido a la propiedad persona.nombre
.
Sin embargo, vamos a probar a acceder a hora a cualquier propiedad del objeto persona
que no exista, como la propiedad persona.altura
:
const altura = proxyPersona.altura;
console.log(altura); // 'Propiedad no encontrada'
Tal y como puedes ver, obtendremos la cadena 'Propiedad no encontrada'
como resultado, que es la que hemos definido.
No solamente estarás limitado al uso del método get()
, ya que también podrás usar muchos otros.
Métodos que puedes usar
Cuando usas un Proxy también puedes usar u observar cualquiera de los métodos que ves a continuación, entre otros:
- construct: El método
construct
es invocado cuando usas el constructor del objeto. - apply: El método
apply
es invocado cuando usas la funciónapply()
sobre el objeto. - get: El método
get
se ejecuta cada vez que intentas acceder a una propiedad del objeto. - set: El método
set
se ejecuta cada vez que intentas modificar una propiedad del objeto. - has: El método
has
se ejecuta cuando compruebas si existe un valor en el objeto mediante dicho método. - deleteProperty: El método
deleteProperty
se ejecuta cada vez que intentas eliminar una propiedad. - defineProperty: El método
defineProperty
se ejecuta cada vez que defines una nueva propiedad. - construct: El método
set
se ejecuta cada vez que intentas modificar una propiedad del objeto.
Tal y como puedes ver, el proxy te permite crear una puerta de entrada mediante la cual poder controlar todo lo que ocurre en el objeto, pudiendo establecer cualquier tipo de regla personalizada, o pudiendo también ejecutar cualquier otra tarea adicional.
También existen muchos otros métodos que puedes utilizar, como por ejemplo los métodos ownKeys
, isExtensible
, preventExtensions
, getPrototypeOf
, setPrototypeOf
o getOwnPropertyDescriptor
, entre otros.
Cómo usar los objetos Proxy
Ya hemos visto en la introducción cómo puedes usar los objetos Proxy, pero vamos a ver otro ejemplo algo más útil en el que usaremos el método deleteProperty
para así evitar el borrado de ciertas propiedades.
Para ello vamos a partir del mismo objeto persona anterior y a declarar otra acción en el handler del proxy:
const persona = {
nombre: 'Edu',
apellido: 'Lazaro'
}
const handler = {
deleteProperty(objeto, prop) {
return false;
} }
Ahora vamos a crear el proxy asignándole el handler al objeto persona:
const proxyPersona = new Proxy(persona, handler):
Si ahora intentas ejecutar la función delete proxyObject.nombre
, obtendrás un error como resultado:
TypeError: 'deleteProperty' on proxy: trap returned falsish for property 'nombre'
Sin embargo, el uso de un proxy no te impedirá usar la función delete persona.nombre
directamente, sobre el propio objeto original. Sin embargo siempre podrías hacer que el objeto original, que en este caso es el objeto persona
, sea inaccesible desde fuera de tu librería, por lo que al no exponerlo, siempre se tendría que usar el proxy para realizar cualquier tipo de tarea con él.
Y esto ha sido todo.
Edu, Gracias por compartir tu conocimiento,