对象代理的实际应用案例
标准定义
Proxy 对象允许您为另一个对象创建代理,该代理可以拦截和重新定义该对象的基本操作。
我们来简化一下。
“使用处理程序自定义对象的行为”——广义上讲。
目标和处理程序
目标是代理所关注的对象。
处理程序或陷阱是作为第二个参数传递的函数,Proxy负责处理目标对象上的操作(例如get,等等)。set
new Proxy(target, handler);
让我们来看一些例子,这些例子将进一步佐证该声明想要表达的意思。
处理默认值
设想一个脚本,用于将获奖者与他们赢得的奖品进行匹配,并且所有参与者都将获得安慰奖。
与使用冗长的语句或 switch 语句相比,更简洁的编码方法if-else是使用Proxy:
const prizeRegistry = {
karen: "First Prize - BMW X5",
mark: "Second Prize - Scooty",
athira: "Third Prize - Bicycle"
};
const prizeHandler = {
get(obj, prop) {
return prop in obj ?
obj[prop] :
"Consolation prize - Chocolate Bar";
}
};
const prizeList = new Proxy(prizeRegistry, prizeHandler);
console.log(prizeList.karen);
// expected output: "First Prize - BMW X5"
console.log(prizeList.reena);
// expected output: "Consolation prize - Chocolate Bar"
输入验证
如今,用户输入已成为大多数应用程序运行过程中不可或缺的一部分。验证机制旨在确保数据的准确性,但讽刺的是,随着时间的推移,负责验证的代码往往会因此而变得混乱不堪。
const validator = {
set(obj, prop, value) {
if (prop === 'weight') {
if (!Number.isInteger(value)) {
throw new TypeError('The weight is not an integer');
}
if (value > 200) {
throw new RangeError('The weight seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
// Indicate success
return true;
}
};
const fish = new Proxy({}, validator);
fish.weight = 100;
console.log(fish.weight);
// expected output: 100
fish.weight = 'small'; // Throws an exception
fish.weight = 300; // Throws an exception
通过属性查找数组项对象
const products = new Proxy([
{ name: 'Firefox', type: 'browser' },
{ name: 'SeaMonkey', type: 'browser' },
{ name: 'Thunderbird', type: 'mailer' }
],
{
get(obj, prop) {
// The default behavior to return the value; prop is usually an integer
if (prop in obj) {
return obj[prop];
}
// Get the number of products; an alias of products.length
if (prop === 'number') {
return obj.length;
}
let result;
const types = {};
for (const product of obj) {
if (product.name === prop) {
result = product;
}
if (types[product.type]) {
types[product.type].push(product);
} else {
types[product.type] = [product];
}
}
// Get a product by name
if (result) {
return result;
}
// Get products by type
if (prop in types) {
return types[prop];
}
// Get product types
if (prop === 'types') {
return Object.keys(types);
}
return undefined;
}
});
console.log(products[0]); // { name: 'Firefox', type: 'browser' }
console.log(products['Firefox']); // { name: 'Firefox', type: 'browser' }
console.log(products['Chrome']); // undefined
console.log(products.browser); // [{ name: 'Firefox', type: 'browser' }, { name: 'SeaMonkey', type: 'browser' }]
console.log(products.types); // ['browser', 'mailer']
console.log(products.number); // 3
以上代码片段来自Mozilla 文档,展示了如何使用代理以最优方式查找对象数组中的对象。
还有许多其他实际用例可以利用其强大的功能Proxy来更好地维护代码并使其更简洁。
PS:这些是我每天都会用到的几个技巧,还有一些其他的,比如DOM操作、属性转发等等。你可以在这里查看。
希望这能帮到你。干杯🍻
文章来源:https://dev.to/jeevankishore/real-world-use-cases-of-object-proxies-3d87
