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

如何结合Proxy与扩展运算符/Object.assign使用并触发代理?

问题核心是扩展运算符会把Proxy代理对象的当前属性值浅拷贝到新对象,新对象和原Proxy完全无关,所以修改新对象的属性根本碰不到原Proxy的set陷阱。

给你两种靠谱的解决思路:


思路一:把methods直接挂载到原Proxy上

既然要让this同时包含store属性和methods方法,直接把methods里的方法加到Proxy对象上就行,这样this绑定的还是原Proxy,修改store属性时自然触发Proxy的set逻辑:

const setup = function (options, cb) {
  // 假设这是你的methods集合
  const methods = {
    printN() {
      console.log("当前n的值:", this.n);
    }
  };

  let store = new Proxy(options.store, {
    set(target, prop, value) {
      console.log(`changed ${prop} from ${target[prop]} to ${value}`);
      target[prop] = value;
      return true;
    },
  });

  // 把methods的方法合并到Proxy对象上
  Object.assign(store, methods);

  // 绑定Proxy后执行回调
  cb.bind(store)();
};

setup(
  {
    store: {
      n: 123,
    },
  },
  function () {
    this.n = 456; // 正常触发Proxy的set
    this.printN(); // 能调用methods里的方法
  }
);

原理:Proxy对象本身是可扩展的(默认配置下),用Object.assign把methods的方法挂载到Proxy上后,回调里的this依然指向原Proxy,修改this.n时还是走Proxy的set陷阱,同时也能直接调用挂载的方法。


思路二:创建新代理转发属性到原Proxy

如果不想修改原Proxy的结构,可以创建一个新的代理对象,把store的属性和methods方法整合进去,同时通过get/set陷阱把属性访问转发到原Proxy:

const setup = function (options, cb) {
  const methods = {
    printN() {
      console.log("当前n的值:", this.n);
    }
  };

  const storeProxy = new Proxy(options.store, {
    set(target, prop, value) {
      console.log(`changed ${prop} from ${target[prop]} to ${value}`);
      target[prop] = value;
      return true;
    },
  });

  // 创建整合后的代理对象
  const combinedProxy = new Proxy(
    { ...methods }, // 先放methods
    {
      // 访问属性时,如果是store里的属性,转发到storeProxy
      get(target, prop) {
        if (prop in storeProxy) {
          return storeProxy[prop];
        }
        return target[prop];
      },
      // 设置属性时,如果是store里的属性,转发到storeProxy
      set(target, prop, value) {
        if (prop in storeProxy) {
          storeProxy[prop] = value;
          return true;
        }
        target[prop] = value;
        return true;
      }
    }
  );

  cb.bind(combinedProxy)();
};

setup(
  {
    store: {
      n: 123,
    },
  },
  function () {
    this.n = 456; // 触发原storeProxy的set
    this.printN(); // 调用methods方法
  }
);

原理:新代理的get/set陷阱会判断当前操作的属性是否属于原store,如果是就转发到原Proxy上执行,这样既保留了methods的独立,又能触发原Proxy的逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 09:25:22