4

我试图通过使用代理覆盖我的对象 getter 来打印出正在通过 getter 访问哪些节点。我试图基本上测试这个大对象的哪些部分没有被我的应用程序使用。我遇到的问题是能够添加一些方法来识别吸气剂父母是什么。这是我到目前为止所拥有的

function tracePropAccess(obj) {
  return new Proxy(obj, {
    get(target, propKey, receiver) {
      console.log("Get fired on ", propKey);
      return Reflect.get(target, propKey, receiver);
    }
  });
}

const testObj = {
  a: 1,
  b: {
    a: "no",
    b: "yes"
  },
  c: {
    a: "green",
    b: {
      a: "blue",
      b: "orange"
    }
  }
};

const tracer = tracePropAccess(testObj);

tracer.b.a;

tracer.a;

tracer.c.c.a;

这非常适合向我展示道具键 - 但它只是第一级的键。我不确定如何使用此代理来解决此问题,因为此单个函数会覆盖所提供对象中的所有代理。有没有办法可能传递对象父母/孩子?可能我也错误地处理了这个问题 - 所以我正在寻找任何输入。谢谢!

4

1 回答 1

4

您可以使用反射并检查它是否是一个对象。如果是,则返回一个代理,如果不是,则返回该值。

它不适用于未完成的对象,因为代理不知道何时将对象作为结果返回或使用代理

例子:

{ foo: { bar: { baz: 42 } } }

tracer.foo.bar

不起作用,因为它应该返回

{ baz: 42 }

但它会返回一个新的代理,这会导致奇怪的结果。主要问题是要知道还有哪些密钥即将到来,并且使用这种表示法,不可能知道下一个或没有密钥是什么。

function tracePropAccess(obj) {
    return new Proxy(obj, {
        get(target, propKey, receiver) {
            console.log("Get fired on ", propKey);
            var temp = Reflect.get(target, propKey, receiver);
            return temp && typeof temp === 'object'
                ? tracePropAccess(temp)
                : temp;
        }
    });
}

const testObj = { a: 1, b: { a: "no", b: "yes" }, c: { a: "green", b: { a: "blue", b: "orange" } } };

const tracer = tracePropAccess(testObj);

console.log(tracer.b.a);
console.log(tracer.a);
console.log(tracer.c.c.a);

带路径

function tracePropAccess(obj, path) {
    path = path || [];
    return new Proxy(obj, {
        get(target, propKey, receiver) {
            var newPath = path.concat(propKey);
            console.log("Get fired on ", newPath);
            var temp = Reflect.get(target, propKey, receiver);
            return temp && typeof temp === 'object'
                ? tracePropAccess(temp, newPath)
                : temp;
        }
    });
}

const testObj = { a: 1, b: { a: "no", b: "yes" }, c: { a: "green", b: { a: "blue", b: "orange" } } };

const tracer = tracePropAccess(testObj);

console.log(tracer.b.a);
console.log(tracer.a);
console.log(tracer.c.c.a);

以路径结尾。

function tracePropAccess(obj, path) {
    path = path || [];
    return new Proxy(obj, {
        get(target, propKey, receiver) {
            var temp = Reflect.get(target, propKey, receiver),
                newPath = path.concat(propKey);
            if (temp && typeof temp === 'object') {
                return tracePropAccess(temp, newPath);
            } else {
                console.log("Get fired on ", newPath);
                return temp;
            }
        }
    });
}

const testObj = { a: 1, b: { a: "no", b: "yes" }, c: { a: "green", b: { a: "blue", b: "orange" } } };

const tracer = tracePropAccess(testObj);

console.log(tracer.b.a);
console.log(tracer.a);
console.log(tracer.c.c.a);

于 2018-03-16T17:55:50.237 回答