前言
Proxy 也就是代理, 可以帮助我们完成很多事情, 例如对数据的处理, 对构造函数的处理, 对数据的验证, 说白了, 就是在我们访问对象前添加了一层拦截, 可以过滤很多操作, 而这些过滤, 由你来定义.
想了解更多请参考 官方文档
语法
let p = new Proxy(target, handler);
参数
target : 需要使用 Proxy 包装的目标对象 (可以是任何类型的对象, 包括原生数组, 函数, 甚至另一个代理).
handler: 一个对象, 其属性是当执行一个操作时定义代理的行为的函数 (可以理解为某种触发器). 具体的 handler 相关函数请查阅官网
下面是使用示例, 一个简单的代理:
- let test = {
- name: "小红"
- };
- test = new Proxy(test, {
- get(target, key) {
- console.log('获取了 getter 属性');
- return target[key];
- }
- });
- console.log(test.name);
上方的案例, 我们首先创建了一个 test 对象, 里面有 name 属性, 然后我们使用 Proxy 将其包装起来, 再返回给 test, 此时的 test 已经成为了一个 Proxy 实例, 我们对其的操作, 都会被 Proxy 拦截.
Proxy 有两个参数, 第一个是 target, 也就是我们传入的 * test 对象, 另一个则是 handler, 也就是我们传入的第二个参数, 一个匿名对象. 在 handler 中定义了一个名叫 get 的函数, 当我们获取 test 的属性时, 则会触发此函数.
咱们再来试试使用 set 来拦截一些操作, 并将 get 返回值更改
- let xiaohong = {
- name: "小红",
- age: 15
- };
- xiaohong = new Proxy(xiaohong, {
- get(target, key) {
- let result = target[key];
- // 如果是获取 money 属性, 则添加 元字
- if (key === "age") result += "岁";
- return result;
- },
- set(target, key, value) {
- if (key === "age" && typeof value !== "number") {
- throw Error("age 字段必须为 Number 类型");
- }
- return Reflect.set(target, key, value);
- }
- });
- console.log(` 我叫 ${xiaohong.name} 我今年 ${xiaohong.age} 了 `);
- xiaohong.age = "aa";
上方案例中定义了 xiaohong 对象, 其中有 age 和 name 两个字段, 我们在 Proxy 中的 get 拦截函数中添加了一个判断, 如果是取 age 属性的值, 则在后面添加 岁. 在 set 拦截函数中判断了如果是更改 age 属性时, 类型不是 Number 则抛出错误. 最后, 正确的输出了我们想要的结果!
关于 return Reflect.set(target, key, value); 这句代码, 可以用其他方式替换, 例如 :
- let xiaohong = {
- name: "小红",
- age: 15
- };
- xiaohong = new Proxy(xiaohong, {
- get(target, key) {
- let result = target[key];
- // 如果是获取 money 属性, 则添加 元字
- if (key === "age") result += "岁";
- return result;
- },
- set(target, key, value) {
- if (key === "age" && typeof value !== "number") {
- throw Error("age 字段必须为 Number 类型");
- }
- target[key] = value;
- // return Reflect.set(target, key, value);
- }
- });
- console.log(` 我叫 ${xiaohong.name} 我今年 ${xiaohong.age} 了 `);
- xiaohong.age = 12;
此时会抛出一个错误, 因为 set 函数必须返回一个 boolean 值, 只有返回值为 true 时才表示修改成功, 我们没有手动 return, 函数会自动返回 undefined,undefined == false, 所以报错是正常的, 只需要手动在最后添加一句 return true 即可!
但是, 既然 JS 为我们提供了 Reflect , 那我们肯定是使用它啦, 毕竟它和 Proxy 本来就是一起玩的, Proxy 有的函数它都有! 具体的参考 官方链接
这只是最基础的应用, 其他的大家可以自行摸索, 都是一样的用法!
打字不易, 点赞的你最靓了...
来源: http://www.jianshu.com/p/77eaaf34e732