You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Proxy检测全局对象及其子属性变动无日志输出问题求助

问题原因

  • 你创建的scopeProxy代理实例没有挂载回全局对象,后续所有修改操作依然作用在原始window.app对象上,不会触发Proxy的拦截钩子。Proxy的拦截逻辑仅对代理实例生效,不会修改原对象本身的行为。
  • 默认Proxy只能监听对象的直接属性变更,无法自动拦截嵌套子属性(比如app.reports.name)的修改,需要手动给嵌套的对象/数组也包裹代理。

修复实现

const scopeHandler = {
  set: function(obj, prop, value) {
    // 新旧值相同则跳过日志输出
    if (obj[prop] === value) return true
    console.log(`${prop} changed from ${obj[prop]} to ${value}`);
    // 新赋值为引用类型时自动包裹代理
    obj[prop] = typeof value === 'object' && value !== null 
      ? new Proxy(value, scopeHandler) 
      : value;
    return true;
  },
  get: function(obj, prop) {
    const value = obj[prop]
    // 读取引用类型属性时提前包裹代理,保证后续子属性修改可被监听
    if (typeof value === 'object' && value !== null) {
      return new Proxy(value, scopeHandler)
    }
    return value
  }
};

// 递归给所有嵌套属性添加代理
function createDeepProxy(target, handler) {
  if (typeof target !== 'object' || target === null) return target
  // 先处理原有嵌套属性
  for (const key in target) {
    target[key] = createDeepProxy(target[key], handler)
  }
  return new Proxy(target, handler)
}

// 将代理实例直接挂载到window.app,后续所有操作都会走代理逻辑
window.app = createDeepProxy(window.app, scopeHandler);

注意事项

  • 如果之前的代码有提前将window.app的引用存储到其他变量的场景,需要将这些引用同步替换为代理实例,否则操作旧引用依然不会触发监听。
  • 该实现可兼容数组类型的监听,包括索引修改、length属性变更的场景。

内容的提问来源于stack exchange,提问作者eozzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 20:15:02