Proxy - JavaScript
O Proxy
Para criar um objeto Proxy
Proxy()
const proxy = new Proxy(target, handler);
Este construtor aceita dois parâmetros:
: o objeto alvo do proxy, que pode ser qualquer objeto ao qual o Proxy é aplicado.target
: outro objeto que define quais operações do objetohandler
serão interceptadas e redefinidas e de que maneira.target
// Objeto ao qual o proxy é aplicado
const target = {name: "Tom"};
// Objeto que define como o target será redefinido
const handler = {};
// Objeto proxy
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Tom
No exemplo acima, target é o objeto ao qual o proxy será aplicado. Neste caso, esse objeto possui a propriedade name
const target = {name: "Tom"};
Em seguida, cria-se um manipulador handler
const handler = {};
Esse objeto deve definir como o objeto target
Então, cria-se o objeto Proxy
target
handler
const proxy = new Proxy(target, handler);
A função de proxy
target
proxy
proxy
name
target
console.log(proxy.name); // Tom
Como utilizamos um handler
target
Redefinindo a Funcionalidade de um Objeto com Proxy
Acima, vimos como criar um proxy para um objeto sem, no entanto, redefinir seu comportamento. O aspecto crucial aqui é o manipulador handler
get
set
Método get e Acesso às Propriedades do Objeto
O método get
const handler = {
get: function(target, prop, receiver) {
return algum_valor;
}
};
O método get
: o próprio objeto proxyado. Esse parâmetro permite acessar a funcionalidade do objeto original.target
: o nome da propriedade que está sendo acessada.prop
: o objetoreceiver
através do qual o proxy está sendo executado.Proxy
Considere o seguinte exemplo:
const target = {name: "Tom"};
const handler = {
get: function(target, prop, receiver) {
return "Tomas Smith";
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Tomas Smith
Neste caso, o manipulador handler
get
get: function(target, prop, receiver) {
return "Tomas Smith";
}
Isso faz com que, ao acessar qualquer propriedade do objeto proxy
console.log(proxy.name); // Tomas Smith
Esse exemplo demonstra como interceptar o acesso a uma propriedade e redefinir a resposta de forma simples. No entanto, ainda podemos acessar o objeto original que está sendo proxyado:
const target = {name: "Tom"};
const handler = {
get: function(target, prop) {
return "Name: " + target.name;
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Name: Tom
Aqui, o manipulador retorna a string "Name: " + target.name
target.name
Considere um objeto mais complexo com duas propriedades:
const target = {name: "Tom", age: 37};
const handler = {
get: function(target, prop) {
return target[prop];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Tom
console.log(proxy.age); // 37
Neste caso, o objeto alvo possui duas propriedades: name
age
return target[prop];
Acesso às propriedades do objeto alvo é feito usando a sintaxe de arrays.
No entanto, podemos verificar qual propriedade está sendo acessada e realizar alguma redefinição:
const target = {name: "Tom", age: 37};
const handler = {
get: function(target, prop) {
if (prop === "name")
return target.name.toUpperCase();
else
return target[prop];
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // TOM
console.log(proxy.age); // 37
Neste exemplo, se o acesso é à propriedade name
toUpperCase()
Configurando Propriedades e o Método set
O método set
const handler = {
set: function(target, property, value, receiver) {
}
};
O método set
: o objeto original que está sendo proxyado.target
: o nome da propriedade que está sendo acessada.property
: o valor que está sendo atribuído.value
: o objetoreceiver
através do qual a operação está sendo realizada.Proxy
Vamos analisar um exemplo:
const target = {name: "Tom", age: 37};
const handler = {
set: function(target, prop, value) {
console.log(value);
target[prop] = value;
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Tomas";
console.log(proxy.name); // Tomas
proxy.age = 22;
console.log(proxy.age); // 22
Neste exemplo, o método set
target[prop] = value;
Agora, vamos modificar o exemplo para incluir uma validação:
const target = {name: "Tom", age: 37};
const handler = {
set: function(target, prop, value) {
if(prop === "age" && value < 1)
console.log("Idade incorreta");
else
return target[prop] = value;
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Tomas";
console.log(proxy.name); // Tomas
proxy.age = -199; // Idade incorreta
console.log(proxy.age); // 37
proxy.age = 22;
console.log(proxy.age); // 22
Neste caso, dentro do método set
age
if(prop === "age" && value < 1)
console.log("Idade incorreta");
Caso contrário, atribuímos o valor à propriedade do objeto original:
else
return target[prop] = value;