proxy能够监听到对象中的对象的引用吗?【热度: 112】

关键词:proxy 监听引用

是的,Proxy 能够监听到对象属性的读取和设置操作,包括对象中嵌套的对象的引用操作。但是,要注意的是,如果你想要监听一个嵌套对象内部的变化(例如,对象的属性或者数组的元素),那么你需要单独为这个嵌套对象也创建一个 Proxy 实例。因为 Proxy 只能直接监听它直接代理的对象的操作,对于嵌套对象的操作,需要嵌套地使用 Proxy 来实现深度监听。

举个例子:

function createDeepProxy(obj) {
  // 递归函数,为对象及其嵌套对象创建代理
  const handler = {
    get(target, property, receiver) {
      const value = Reflect.get(target, property, receiver);
      if (typeof value === "object" && value !== null) {
        // 如果属性是对象(且非 null),则为该属性也创建代理
        return createDeepProxy(value);
      }
      return value;
    },
    set(target, property, value, receiver) {
      console.log(`Setting property ${property} to ${value}`);
      return Reflect.set(target, property, value, receiver);
    },
  };

  return new Proxy(obj, handler);
}

const original = { name: "John", address: { city: "New York" } };

const proxied = createDeepProxy(original);

proxied.address.city = "San Francisco"; // 控制台输出:Setting property city to San Francisco
console.log(original.address.city); // 输出 San Francisco

在这个例子中,createDeepProxy 函数使用了递归,为对象及其所有嵌套对象创建了 Proxy 代理。因此,修改嵌套对象 address 下的 city 属性时,set 陷阱(trap)被触发,并且控制台有相应的输出。但注意这种递归创建 Proxy 的做法可能会带来性能问题,特别是在处理有很深嵌套结构或者很大的对象时。

此外,需要留意的是,由于每次访问嵌套对象时都会动态创建新的 Proxy 实例,这可能导致一些意料之外的行为,比如基于身份的比较或引用检查可能会失败。因此,在实际应用中,应根据需求精心设计 Proxy 的使用方式。