如何监听对象所有属性(含后续新增属性)的读取操作?
解决直接访问对象任意属性(含新增)时触发处理函数的问题
看起来你已经摸到了关键痛点——现有两种方案要么只能通过代理实例触发,要么覆盖不了新增属性。其实核心解法很简单:直接让你的obj变量指向Proxy实例,而不是保留原空对象的引用。
这样不管是访问已存在的属性,还是后续新增的属性,只要通过obj访问,都会触发Proxy的陷阱函数。直接看代码:
// 直接将obj定义为Proxy实例,无需单独的原对象 var obj = new Proxy({}, { get(target, prop) { console.log('get', prop); // 用Reflect.get保证默认的属性访问行为 return Reflect.get(target, prop); }, // 可选:如果需要监听属性设置,也可以加上set陷阱 set(target, prop, value) { console.log('set', prop, value); return Reflect.set(target, prop, value); } }); // 测试一下 obj.name = "Alice"; // 输出: set name Alice console.log(obj.name); // 输出: get name 然后 Alice console.log(obj.age); // 输出: get age 然后 undefined
为什么这个方案可行?
之前你把Proxy存在proxy变量里,obj还是原来的空对象——原对象本身没有任何拦截逻辑,所以直接访问obj自然不会触发函数。现在让obj本身就是代理对象,所有对它的属性操作都会经过Proxy的拦截陷阱,不管是一开始就有的属性,还是后续动态新增的,都能被捕获到。
如果必须保留原对象的引用怎么办?
如果因为历史代码或其他原因,没办法让obj指向Proxy,那其实没有原生的完美解决方案——JavaScript的普通对象本身不支持“自动拦截所有新增属性访问”的机制。这时候只能尽量让所有属性访问都通过Proxy实例,或者放弃原生方案使用第三方库(比如Vue 2的响应式原理就是结合defineProperty和递归监听,但也需要手动处理新增属性)。不过最可靠、最符合现代JS规范的方式还是上面的Proxy方案。
内容的提问来源于stack exchange,提问作者junvar
相关产品推荐
相关产品推荐

