“这是我参与更文挑战的第5天,活动详情查看: 更文挑战”
Proxy 按字面意思就是代理,其 API官方使用手册见 MDN
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
我们将 Proxy 理解为现实生活中的代理商,通过几个常见的卖货场景来学习一下 Proxy。
一个新手代理商
一个新手代理商,一脸懵逼,只管代理了,但啥都不干啥。
const target = {
who: "我是谁?",
where: "我在哪里?"
};
const handler1 = {};
const proxy1 = new Proxy(target, handler1);
console.log(proxy1.who); // => 我是谁?
console.log(proxy1.where); // => 我在哪里?
复制代码
一个开始知道赚钱的代理商
懵逼之后,开始上道,代理的本质是要赚钱,所以我们统一将售价对外展示为成本价的 1.5 倍吧。
const originPrice = {
water: 10,
rice: 20
};
const handler2 = {
get(target, key) {
return target[key] * 1.5;
}
};
const soldPrice = new Proxy(originPrice, handler2);
console.log(soldPrice.water); // => 15
console.log(soldPrice.rice); // => 30
复制代码
一个开始懂得处理库存的代理商
做生意很关键的一点的要管理好库存信息,知道库存才知道什么时候好进货,以及进多少。
const quantity = {
water: 5,
rice: 3
};
const handler3 = {
set(target, key, value) {
target[key] = value;
console.log(`更新${key}的库存为${value}`);
return true;
}
};
const quantitySet = new Proxy(quantity, handler3);
quantitySet.water = 15; // => 更新water的库存为15
quantitySet.rice = 13; // => 更新rice的库存为13
console.log(quantitySet.water); // => 15
console.log(quantitySet.rice); // => 13
复制代码
某一天,太忙懵逼了,一不小心库存输入太大了,导致货不对量了。所以我们还可以加入一个输入限制。
const quantity = {
rice: 3
};
const handler3 = {
set(target, key, value) {
if (value > 100) {
console.log(`${key}的库存怕不是搞错了吧。再复核一下?`)
return false;
}
target[key] = value;
console.log(`更新${key}的库存为${value}`);
return true;
}
};
...
quantitySet.rice = 101; // => rice的库存怕不是搞错了吧。再复核一下?
console.log(quantitySet.rice); // => 3
复制代码
一个开始懂得捂货的代理商
好东西坚决不卖~捂着先。开始奸商之道。
const goods = {
'矿泉水': 100,
'茅台': 10,
_privateDVD: 10,
};
const handler4 = {
has(target, key) {
if (key === '茅台' || key.startsWith('_')) {
console.log('打死我都不会承认自己有的');
return false;
}
console.log('有有有,大量的有');
return Reflect.get(target, key);
}
};
const sellGoods = new Proxy(goods, handler4);
console.log('茅台' in sellGoods); // false
console.log('_privateDVD' in sellGoods); // false
console.log('矿泉水' in sellGoods); // true
复制代码
一个亏本清仓甩卖的代理商
不说了,流过的眼泪就是自己的智商税。
const goodsInfo = {
'saltWater': 100,
'茅台': 1,
'_privateDVD': 1
};
const readonlyKeys = ['茅台', '_privateDVD'];
const sellGoods2 = new Proxy(goodsInfo, {
deleteProperty(target, key) {
if (readonlyKeys.includes(key)) {
throw new Error(`${key}这种货怎么可能清仓`);
return;
}
console.log(`delete: ${key}`);
delete target[key];
return true;
}
});
console.log(sellGoods2.saltWater, goodsInfo.saltWater); // => 100 100
delete sellGoods2.saltWater; // => delete: saltWater
console.log(sellGoods2.saltWater, goodsInfo.saltWater); // => undefined undefined
// delete sellGoods2['茅台']; // => throw error
delete sellGoods2['_privateDVD']; // => throw error
复制代码
Proxy的小结
通过上面的几个案例,我想我们对 Proxy 代理之路已经有了初步的概念。文中出现的几个 handler
- get handler
- set handler
- has handler
- deleteProperty handler
是 Proxy 最常见的几种 handler,我们可以在代理上原始的 target 之后,再封装自己的业务逻辑。
其强大的特性也被 vue3 所直接使用,性能进而得到了大幅提升。
但其最大的兼容性问题是不被 IE 支持,这也是为什么 vue3 放弃 IE 的原因了。
你会在项目中使用 Proxy 吗。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END