在javascript中向代理添加(递归?)级别感知

时间:2018-03-16 17:21:22

标签: javascript ecmascript-6 es6-proxy

我试图通过使用代理覆盖我的对象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;

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

1 个答案:

答案 0 :(得分:2)

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

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

示例:

{ 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);