← 返回目录

Proxy

Proxy 就是给对象请个"经纪人"。以后对对象的读写操作,都先经过经纪人,经纪人能拦截、能加工、能把关。

1. 没有代理 vs 有代理

以前 · 直接访问对象 现在 · Proxy 代理拦截
let target = { name: "John" };
console.log(target.name);
// John(直接拿结果)
console.log(target.age);
// undefined(没有就没有,拦不住)
let target = { name: "John" };
let handler = {
  get(target, prop) {   // 拦截"读"
    if (prop === "age") return 30;
    return target[prop];
  }
};
let proxy = new Proxy(target, handler);
console.log(proxy.name);
// John
console.log(proxy.age);
// 30(被经纪人加工了)

没代理时,读属性直接拿结果,想做手脚没机会;有了 Proxy,每次读写都先过 handler,经纪人想怎么处理就怎么处理。

2. set:拦截"写"属性

let target = { name: "John" };
let handler = {
  set(target, prop, value) {
    console.log("有人要把 " + prop + " 改成 " + value);
    target[prop] = value;   // 真正写入
    return true;
  }
};
let proxy = new Proxy(target, handler);
proxy.skill = "前端";
// 打印:有人要把 skill 改成 前端
	

每次给对象赋值,都会被 set 拦截到。用它可以做记日志、校验、提示

3. 真实用途:数据校验(把关)

let user = { age: 20 };
let handler = {
  set(target, prop, value) {
    if (prop === "age" && value < 0) {
      console.log("年龄不能是负数!");
      return false;    // 拒绝写入
    }
    target[prop] = value;
    return true;
  }
};
let proxy = new Proxy(user, handler);

proxy.age = -5;
// 打印:年龄不能是负数!
console.log(proxy.age);
// 20(没写进去,还是原来的值)
	

写数据之前先"把关",不合规的直接拦下来,这就是 Proxy 最常见的用法。

一句话:Proxy = 给对象请个经纪人,读属性走 get,写属性走 set,能拦截、能加工、能把关。