I am trying to print out which nodes are being accessed via the getter by overriding my objects getter with a proxy. I am trying to basically test which parts of this large object are not being used by my application. The problem I am having is being able to add some way of identifying what a getters parents are. Here is what I have so far
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;
This works great in showing me the prop key - however it only the key from the first level. I am not sure how to approach this with this proxy as this single function overrides all the proxies in the provided object. Is there any way to possibly pass in an objects parents/children? Possibly I am approaching this incorrectly as well - so I am looking for any input. Thanks!
You could use the reflection and check if it is an object. If so, return a proxy, if not, return the value.
It does not work on unfinished objects, because the proxy does not know when an object is returned as result or a proxy is to use
Example:
{ foo: { bar: { baz: 42 } } }
and
tracer.foo.bar
does not work, because it should return
{ baz: 42 }
but it returns a new proxy instead, which leads to strange results. The main problem is to know which more keys are coming and with this notation, it is impossible to know what the next or no key is.
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);
With path
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);
With path at the end.
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);