如何代理JavaScript函数生成的嵌套数组以监控数据变更?
解决嵌套数组/对象的Proxy监控问题
问题核心
你需要监控嵌套数组中对象的指定字段变更,用来触发表格更新,但之前的方案遇到undefined报错,主要原因包括:
- 错误访问不存在的属性(比如测试代码里的
proxy.string) - 带空格的属性用了点语法访问(正确方式是方括号)
- 原Proxy逻辑对数组的处理不够严谨
修正后的Proxy实现
下面是针对你的需求优化后的代码,只监控指定字段,同时正确处理嵌套数组和带空格的属性:
// 要监控的目标字段列表 const WATCHED_FIELDS = new Set([ 'Service', 'Authorization', 'Client Waiver Due', '90 Day Progress' ]); const handler = { get(target, key) { // 处理数组的索引(比如'0'、'1')和对象的键 const prop = target[key]; // 如果是不存在的属性,直接返回 if (typeof prop === 'undefined') return prop; // 如果是对象/数组且未被代理,就包装成Proxy if (typeof prop === 'object' && prop !== null && !prop._isProxy) { const proxy = new Proxy(prop, handler); // 标记已代理,避免重复包装 prop._isProxy = true; target[key] = proxy; } return target[key]; }, set(target, key, value) { // 只在修改目标字段时触发更新逻辑 if (WATCHED_FIELDS.has(key)) { console.log(`字段 ${key} 从 ${target[key]} 变更为 ${value}`); // 这里写你的表格更新逻辑,比如调用渲染函数 // updateTable(); } // 处理数组的长度变更(比如push、splice后长度变化) if (Array.isArray(target) && key === 'length') { console.log('数组长度变更,触发表格更新'); // updateTable(); } // 完成赋值 target[key] = value; return true; } }; // 测试数据(和你的结构匹配) const data = [ { 'Service': 'On Site', 'Authorization': '4/15/22', 'Client Waiver Due': '4/15/22', '90 Day Progress': '1' }, { 'Service': 'Off Site', 'Authorization': '7/15/22', 'Client Waiver Due': '7/15/22', '90 Day Progress': '0' } ]; // 创建代理 const proxyData = new Proxy(data, handler); // 测试修改指定字段 proxyData[0]['Service'] = 'Remote Site'; // 会触发监控日志 proxyData[1]['90 Day Progress'] = '1'; // 会触发监控日志 // 测试添加新数组元素(会触发长度变更监控) proxyData.push({ 'Service': 'Hybrid', 'Authorization': '10/15/22', 'Client Waiver Due': '10/15/22', '90 Day Progress': '0' }); // 错误示例:带空格的属性不能用点语法,必须用方括号 // 错误写法:proxyData[0].Client Waiver Due // 正确写法:proxyData[0]['Client Waiver Due']
关键说明
- 带空格属性的访问:必须用方括号语法
obj['Key With Spaces'],点语法只支持合法标识符(不能有空格、不能以数字开头)。 - 只监控指定字段:用
Set存储目标字段,在set方法里判断,避免无关字段的变更触发更新。 - 数组处理:额外监控
length属性的变更,因为数组的push、splice等操作会修改length,此时需要触发表格更新。 - 避免重复代理:用
_isProxy标记已代理的对象,防止每次访问都重新创建Proxy。
原测试代码的问题解释
你之前的测试代码里访问proxy.string、proxy.object这些属性,原本的test数组里根本没有这些属性,所以会返回undefined,这是测试代码的错误,不是Proxy逻辑的问题。
内容的提问来源于stack exchange,提问作者UmaLPZ
相关产品推荐
相关产品推荐

