如何在Proxy中定义与getter、setter类似的删除操作拦截器
Proxy实现嵌套对象属性删除操作拦截方案
核心修改点
- 新增Proxy的
deleteProperty捕获器,用于拦截delete操作,可在内部实现自定义监听逻辑 - 优化原
get捕获器逻辑:访问到嵌套对象/数组时自动套代理,保证所有层级的属性操作都能被捕获(原逻辑仅在赋值时给新对象套代理,原始嵌套对象的操作无法拦截)
完整实现代码
/* This function takes an object and converts to a proxy object. It also takes care of proxying nested objects and array. */ let getProxy = (original) => { return new Proxy(original, { get(target, name, receiver) { let rv = Reflect.get(target, name, receiver); // 嵌套对象访问时自动套代理,保证全层级操作可拦截 if (typeof rv === 'object' && rv !== null) { return getProxy(rv); } return rv; }, set(target, name, value, receiver) { // Proxies new objects if(typeof value === "object" && value !== null){ value = getProxy(value); } // 可在此处补充set操作的自定义监听逻辑 return Reflect.set(target, name, value, receiver); }, // 新增删除操作拦截器 deleteProperty(target, name) { // 此处编写自定义监听逻辑,比如状态同步、变更上报等 console.log(`触发属性删除:删除的属性名是 ${String(name)}`); // 执行实际删除操作,返回删除是否成功的布尔值 return Reflect.deleteProperty(target, name); } }) } let first = {}; let proxy = getProxy(first); /* Here are the tests */ proxy.name={} // object proxy.name.first={} // nested object proxy.name.first.names=[] // nested array proxy.name.first.names[0]={first:"vetri"} // nested array with an object // 删除操作测试 delete proxy.name.first.names[0]; // 触发删除监听 delete proxy.name.first; // 触发删除监听 /* Here are the serialised values */ console.log(JSON.stringify(first)) // {"name":{}} console.log(JSON.stringify(proxy)) // {"name":{}}
逻辑说明
- 所有层级的属性删除操作都会触发
deleteProperty内的自定义逻辑,覆盖嵌套对象属性、数组元素等场景 - 删除操作会同步作用到原始对象,和原有的set/get逻辑保持行为一致
内容的提问来源于stack exchange,提问作者Vetrivel
相关产品推荐
相关产品推荐

