javascript 代理
I've always loved the flexibility of Objects and prototypes in JavaScript, but for a long time, I felt that a level of dynamism was lacking. JavaScript eventually added get
and set
methods for object properties, which was an awesome step, but there was still room for improvement.
我一直很喜欢JavaScript中对象和原型的灵活性,但是很长一段时间以来,我感到缺乏一定的活力。 JavaScript最终为对象属性添加了get
和set
方法,这是一个了不起的步骤,但仍有改进的空间。
The JavaScript Proxy API was an awesome improvement: a virtualizing interface to control the modification behavior of an object!
JavaScript Proxy API进行了令人敬畏的改进:虚拟化界面可以控制对象的修改行为!
代理格式 (Proxy Format)
Proxy accepts an object to proxy for and an object with handlers ("traps") for get
, set
, has
and other common object methods:
Proxy接受一个要代理的对象,以及一个带有用于get
, set
, has
和其他常见对象方法的处理程序(“陷阱”)的对象:
const proxy = new Proxy({}, {
get: (obj, prop) => { ... },
set: (obj, prop, value) => { ... },
// more props here
});
Any attempt to set or get a property is run through the trap, allowing you to run additional logic, especially if the property is unwanted, doesn't exist, or requires validation.
设置或获取属性的任何尝试都将通过陷阱进行,从而允许您运行其他逻辑,尤其是在该属性是不需要的,不存在或需要验证的情况下。
基本用法 (Basic Usage)
Let's create a basic proxy that returns defaults for any given property:
让我们创建一个基本代理,该代理返回任何给定属性的默认值:
const proxy = new Proxy({}, {
get: (obj, prop) => {
return prop in obj ? obj[prop] : null;
}
});
// proxy.whatever => null
The example above illustrates that no matter the property the code attempts to set, your Proxy logic can capture and modify it as desired. Instead of undefined
being returned for a property that doesn't exist, you can instead return null
.
上面的示例说明,无论代码尝试设置的属性是什么,您的代理逻辑都可以根据需要捕获和修改它。 您可以返回null
,而不是为不存在的属性返回undefined
。
验证方式 (Validation)
The most obvious and useful usage of Proxy is validation; since you monitor validate any property coming in, you can keep your data as pure as possible.
Proxy最明显和最有用的用法是验证。 由于监视程序可以验证传入的任何属性,因此您可以保持数据尽可能纯净。
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
You can choose to modify incoming data like the example above, or you can throw an error:
您可以选择像上面的示例一样修改传入的数据,也可以引发错误:
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!
调试 (Debugging)
You can even use Proxy to provide yourself debugging points or events to see how and when values are being set and retrieved:
您甚至可以使用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
Even if you don't modify any input or output, having a hook to value changes on an object is incredibly valuable.
即使您不修改任何输入或输出,钩住对象上的值更改也非常有价值。
格式化 (Formatting)
Another simple usage is formatting data that comes into the object:
另一个简单的用法是格式化对象中的数据:
const proxy = new Proxy({}, {
set: (obj, prop, value) => {
if (prop === "age") {
obj[prop] = Number(value);
}
}
});
proxy.prop = "1"; // 1
You can format from String to Number, Number to String, or simply set defaults.
您可以将格式设置为“字符串”到“数字”,“数字”到“字符串”,或者直接设置默认值。
对现有对象使用代理 (Using Proxies with Existing Objects)
In the examples provided above, we use an empty object ({}
), but you can also use an existing object:
在上面提供的示例中,我们使用一个空对象( {}
),但是您也可以使用一个现有对象:
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"
Note that the original object does change, as well as the proxy, so the proxy does not act as a "copy", so to speak.
请注意,原始对象和代理都发生了更改,因此可以说代理不充当“副本”。
People love to hate on PHP but one thing I loved about the language was "magic properties" that you could spy on and dynamically react to. The Proxy API feels like JavaScript's answer to that. The more you can control what's coming and going out, the better your application can become!
人们喜欢讨厌PHP,但是我最喜欢该语言的一件事是您可以窥探并动态React的“魔术属性”。 Proxy API就像是JavaScript的答案。 您可以控制进出的内容越多,您的应用程序就可以变得更好!
javascript 代理