Patrones de Diseño: Patrón de Proxy (Página 3)

Con un objeto Proxy, tenemos más control sobre las interacciones con ciertos objetos. Un objeto proxy puede determinar el comportamiento cada vez que interactuamos con el objeto, por ejemplo cuando obtenemos un valor o establecemos un valor.


En términos generales, un apoderado significa un sustituto de otra persona. En lugar de hablar con esa persona directamente, hablará con la persona apoderada que representará a la persona con la que intenta comunicarse. Lo mismo sucede en JavaScript: en lugar de interactuar directamente con el objeto de destino, interactuaremos con el objeto Proxy.

const person = {
name: "John Doe",
age: 42,
nationality: "American",
};

En lugar de interactuar directamente con este objeto, queremos interactuar con un objeto proxy. En JavaScript, podemos crear fácilmente un nuevo proxy creando una nueva instancia de Proxy .

const person = {
name: "John Doe",
age: 42,
nationality: "American",
};
const personProxy = new Proxy(person, {});

El segundo argumento de Proxy es un objeto que representa al controlador . En el objeto controlador, podemos definir un comportamiento específico según el tipo de interacción. Aunque hay muchos métodos que puedes agregar al controlador de Proxy, los dos más comunes son get y set :

  • get : Se invoca al intentar acceder a una propiedad.
  • set : Se invoca al intentar modificar una propiedad.

En lugar de interactuar con el person objeto directamente, interactuaremos con el personProxy .

Agreguemos controladores al personProxy Proxy. Al intentar modificar una propiedad, invocando así el set método en Proxy , queremos que el proxy registre el valor anterior y el nuevo valor de la propiedad. Al intentar acceder a una propiedad, invocando así el get método en Proxy , queremos que el proxy registre una oración más legible que contenga la clave y el valor de la propiedad.

const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${obj[prop]}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
obj[prop] = value;
},
});

Al acceder a la name propiedad, el Proxy devolvió una frase que suena mejor: The value of name is John Doe .

Al modificar la age propiedad, el Proxy devolvió el valor anterior y nuevo de esta propiedad: Changed age from 42 to 43 .


Un proxy puede resultar útil para agregar validación . Un usuario no debería poder cambiar person la edad de a un valor de cadena ni darle un nombre vacío. O si el usuario está intentando acceder a una propiedad del objeto que no existe, debemos informarle.

const personProxy = new Proxy(person, {
get: (obj, prop) => {
if (!obj[prop]) {
console.log(
`Hmm.. this property doesn't seem to exist on the target object`
);
} else {
console.log(`The value of ${prop} is ${obj[prop]}`);
}
},
set: (obj, prop, value) => {
if (prop === "age" && typeof value !== "number") {
console.log(`Sorry, you can only pass numeric values for age.`);
} else if (prop === "name" && value.length < 2) {
console.log(`You need to provide a valid name.`);
} else {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}.`);
obj[prop] = value;
}
},
});

El proxy se aseguró de que no estuviéramos modificando el person objeto con valores defectuosos, lo que nos ayuda a mantener nuestros datos puros.


Reflect

JavaScript proporciona un objeto integrado llamado Reflect , que nos facilita la manipulación del objeto de destino cuando trabajamos con servidores proxy.

Anteriormente, intentamos modificar y acceder a las propiedades del objeto de destino dentro del proxy obteniendo o configurando directamente los valores con notación entre corchetes. En su lugar, podemos usar el Reflect objeto. Los métodos del Reflect objeto tienen el mismo nombre que los métodos del handler objeto.

En lugar de acceder a las propiedades obj[prop] o establecer propiedades mediante obj[prop] = value , podemos acceder o modificar las propiedades del objeto de destino mediante Reflect.get() y Reflect.set() . Los métodos reciben los mismos argumentos que los métodos del objeto controlador.

const personProxy = new Proxy(person, {
get: (obj, prop) => {
console.log(`The value of ${prop} is ${Reflect.get(obj, prop)}`);
},
set: (obj, prop, value) => {
console.log(`Changed ${prop} from ${obj[prop]} to ${value}`);
Reflect.set(obj, prop, value);
},
});

Compensaciones

Los proxies son una forma poderosa de agregar control sobre el comportamiento de un objeto. Un proxy puede tener varios casos de uso: puede ayudar con la validación, el formateo, las notificaciones o la depuración.

El uso excesivo del Proxy objeto o la realización de operaciones intensas en cada handler invocación de método pueden afectar fácilmente el rendimiento de su aplicación de forma negativa. Es mejor no utilizar servidores proxy para código crítico para el rendimiento.

🔥 RELACIONADOS