Proxy 包裹目标对象,拦截 get/set/has/deleteProperty 等十几种操作——读拦截、写校验、变更通知都能在「不改原对象」的前提下完成。Vue 3 的响应式就是用 Proxy 重写的(替代了 Vue 2 的 defineProperty),用 Proxy 可以监听到「新增属性」「数组下标赋值」这类 defineProperty 的死角。
Reflect 与 Proxy 的拦截方法一一对应(Reflect.get/set/has…)。写拦截器时用 Reflect 转发原行为,天然处理好 receiver(绑定的 this)问题,比直接 target[key] 更稳。
const data = { name: 'x', age: 0 }; const proxy = new Proxy(data, { get(target, key, receiver) { console.log('读取', key); return Reflect.get(target, key, receiver); // 转发原行为 }, set(target, key, val, receiver) { if (key === 'age' && val < 0) { // 写校验 console.warn('年龄不能为负'); return false; } console.log('修改', key, '=>', val); return Reflect.set(target, key, val, receiver); }, }); proxy.name; // 打印:读取 name proxy.age = -1; // 打印:年龄不能为负(赋值被拒绝) proxy.newProp = 1; // 拦截「新增属性」——defineProperty 做不到