发布于:2021-01-24 00:00:57
0
87
0
我一直都很喜欢JavaScript中对象和原型的灵活性,但很长一段时间以来,我觉得缺乏一定程度的动态性。JavaScript最终为对象属性添加了get和set方法,这是一个很棒的步骤,但仍然有改进的空间。
JavaScript代理API是一个令人敬畏的改进:一个控制对象修改行为的虚拟化接口!
代理的格式
代理接受一个要代理的对象,以及一个带有get、set、has和其他常见对象方法处理程序(“陷阱”)的对象:
const proxy = new Proxy({}, { get: (obj, prop) => { ... }, set: (obj, prop, value) => { ... }, // more props here });
任何设置或获取属性的尝试都将通过该陷阱运行,从而允许您运行额外的逻辑,特别是当该属性不需要、不存在或需要验证时。
基本用法
让我们创建一个基本的代理,为任何给定的属性返回默认值:
const proxy = new Proxy({}, { get: (obj, prop) => { return prop in obj ? obj[prop] : null; } }); // proxy.whatever => null
上面的示例说明了,无论代码试图设置什么属性,您的代理逻辑都可以根据需要捕获并修改它。对于不存在的属性,可以返回null,而不是undefined。
验证
代理最明显和最有用的用法是验证;由于您可以监视并验证传入的任何属性,所以可以尽可能地保持数据的纯粹性。
const proxy = new Proxy({}, { set: (obj, prop, value) => { // Don't allow age > 100 if (prop === "age" && value > 100) { // Set to max age value = 100; } obj[prop] = value; } }); proxy.age = 120; proxy.age; // 100
你可以选择像上面的例子那样修改传入的数据,或者你可以抛出一个错误:
const proxy = new Proxy({}, { set: (obj, prop, value) => { // Ensure age is of type Number if (prop === "age" && isNaN(value)) { throw new Error("Invalid age value!"); return; } obj[prop] = value; } }); proxy.age = "yes"; // Uncaught error: Invalid age value!
调试
你甚至可以使用Proxy来为自己提供调试点或事件,以查看如何以及何时设置和获取值:
const proxy = new Proxy({}, { set: (obj, prop, value) => { console.log(`Setting ${prop} from ${obj[prop]} to ${value}`); obj[prop] = value; } }); proxy.prop = 1; proxy.prop = 2; // Setting prop from undefined to 1 // Setting prop from 1 to 2
即使您不修改任何输入或输出,拥有一个对象上值更改的挂钩也是非常有价值的。
格式化
另一个简单的用法是格式化进入对象的数据:
const proxy = new Proxy({}, { set: (obj, prop, value) => { if (prop === "age") { obj[prop] = Number(value); } } }); proxy.prop = "1"; // 1
您可以格式化字符串到数字,数字到字符串,或简单地设置默认值。
使用现有对象的代理
在上面的例子中,我们使用了空对象({}),但你也可以使用现有的对象:
const myObj = { x: "x", y: "y" }; // Use existing object, simply set value as is given const proxy = new Proxy(myObj, { set: (obj, prop, value) => { obj[prop] = value; } }); // proxy.x = "XXX"; proxy.x; // "XXX" myObj.x; // "XXX"
请注意,原始对象和代理都会发生变化,因此代理不能充当“副本”。
人们讨厌PHP,但我喜欢这门语言的一点是你可以监视和动态响应的“魔法属性”。代理API感觉像是JavaScript对这个问题的回答。你能控制的东西越多,你的应用就会变得越好!
作者介绍