proxy 监控对象属性增删需拦截 set 和 deleteproperty 操作,set 可区分新增与修改并捕获数组操作,deleteproperty 仅响应显式删除;需用 reflect 转发以保语义,且仅代理第一层,深层嵌套需递归处理。

使用 Proxy 监控对象属性的增删,核心在于拦截 set(新增/修改)和 deleteProperty(删除)操作。它比 Object.defineProperty 更全面,能捕获动态添加、删除属性的行为,且对嵌套对象需配合递归或 Reflect 实现深度监听。
监听属性新增与修改(set 拦截)
set 拦截器会在给目标对象赋值时触发,无论该属性原本是否存在。你可以借此判断是新增还是修改,并执行相应逻辑。
- 用
Reflect.has(target, key)判断属性是否已存在,区分新增与修改 - 必须返回
true才能让赋值生效(否则静默失败),推荐用Reflect.set(...)转发操作 - 注意:对数组索引赋值(如
arr[0] = x)、length 修改、push 等也走set,可一并捕获
监听属性删除(deleteProperty 拦截)
deleteProperty 在调用 delete obj.key 或 Reflect.deleteProperty(obj, key) 时触发,适用于监控显式删除行为。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 拦截器中可打印日志、触发回调、阻止删除(返回
false)等 - 同样建议用
Reflect.deleteProperty(target, key)转发,保证原语义 - 注意:
obj.key = undefined不算删除,不会触发此拦截;只有delete或Reflect.deleteProperty才会
基础监控示例(含新增/删除日志)
以下是一个轻量级监控代理,记录属性新增、修改和删除:
const observe = (obj) => {
return new Proxy(obj, {
set(target, key, value, receiver) {
const existed = Reflect.has(target, key);
console.log(`${existed ? '修改' : '新增'}属性 "${key}":`, value);
return Reflect.set(target, key, value, receiver);
},
deleteProperty(target, key) {
console.log(`删除属性 "${key}"`);
return Reflect.deleteProperty(target, key);
}
});
};
const data = { a: 1 };
const proxy = observe(data);
proxy.b = 2; // 新增属性 "b": 2
proxy.a = 99; // 修改属性 "a": 99
delete proxy.b; // 删除属性 "b"
注意事项与常见陷阱
Proxy 监控有其边界,实际使用需留意:
- Proxy 只代理第一层,深层嵌套对象需手动递归 wrap 或结合
get拦截实现懒代理 - 不能监听原型链上的属性访问或修改,只作用于目标对象自身
- 原对象仍可绕过 Proxy 直接操作,应避免暴露原始对象引用
- for...in、Object.keys() 等枚举操作不受
set/deleteProperty影响,如需拦截需配合ownKeys和has










