在 javascript 中向代理添加(递归?)级别感知
Adding (recursion?) level awareness to proxy in javascript
我试图通过使用代理覆盖我的 objects getter 来打印出哪些节点正在通过 getter 访问。我正在尝试基本上测试我的应用程序未使用这个大 object 的哪些部分。我遇到的问题是能够添加一些方法来识别 getters parents 是什么。这是我目前所拥有的
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;
这非常适合向我展示道具钥匙 - 但它只是 第一级 的钥匙。我不确定如何使用这个代理来解决这个问题,因为这个单一函数会覆盖所提供的 object 中的所有代理。有什么方法可以传入 objects parents/children 吗?可能我也在错误地处理这个问题 - 所以我正在寻找任何输入。谢谢!
您可以使用反射并检查它是否是一个对象。如果是,return 代理,如果不是,return 值。
它不适用于未完成的对象,因为代理不知道对象何时被 returned 或代理何时使用
示例:
{ foo: { bar: { baz: 42 } } }
和
tracer.foo.bar
不起作用,因为它应该 return
{ baz: 42 }
但它 return 是一个新的代理,这会导致奇怪的结果。主要问题是要知道接下来还有哪些键,使用这种表示法,不可能知道下一个或没有键是什么。
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);
我遇到了同样的需求,研究的时候遇到了这个问题。
这可以通过为代理陷阱创建一个工厂函数来解决,该工厂函数递归地在对象内添加当前路径:
const reporter = (path = []) => ({
get(target, property) {
console.log(`getting ${path.concat(property).join('.')}`)
const value = Reflect.get(target, property)
if (typeof value === 'object') {
return new Proxy(value, reporter(path.concat(property)))
} else {
return value
}
},
})
const o = new Proxy({
a: 1,
b: {
c: 2,
d: [ 3 ],
},
}, reporter())
let tmp = o.a // 1, logs a
tmp = o.b.c // 2, logs b, b.c
tmp = o.b.d[0] // 3 logs b, b.d, b.d.0
我试图通过使用代理覆盖我的 objects getter 来打印出哪些节点正在通过 getter 访问。我正在尝试基本上测试我的应用程序未使用这个大 object 的哪些部分。我遇到的问题是能够添加一些方法来识别 getters parents 是什么。这是我目前所拥有的
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;
这非常适合向我展示道具钥匙 - 但它只是 第一级 的钥匙。我不确定如何使用这个代理来解决这个问题,因为这个单一函数会覆盖所提供的 object 中的所有代理。有什么方法可以传入 objects parents/children 吗?可能我也在错误地处理这个问题 - 所以我正在寻找任何输入。谢谢!
您可以使用反射并检查它是否是一个对象。如果是,return 代理,如果不是,return 值。
它不适用于未完成的对象,因为代理不知道对象何时被 returned 或代理何时使用
示例:
{ foo: { bar: { baz: 42 } } }
和
tracer.foo.bar
不起作用,因为它应该 return
{ baz: 42 }
但它 return 是一个新的代理,这会导致奇怪的结果。主要问题是要知道接下来还有哪些键,使用这种表示法,不可能知道下一个或没有键是什么。
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);
我遇到了同样的需求,研究的时候遇到了这个问题。
这可以通过为代理陷阱创建一个工厂函数来解决,该工厂函数递归地在对象内添加当前路径:
const reporter = (path = []) => ({
get(target, property) {
console.log(`getting ${path.concat(property).join('.')}`)
const value = Reflect.get(target, property)
if (typeof value === 'object') {
return new Proxy(value, reporter(path.concat(property)))
} else {
return value
}
},
})
const o = new Proxy({
a: 1,
b: {
c: 2,
d: [ 3 ],
},
}, reporter())
let tmp = o.a // 1, logs a
tmp = o.b.c // 2, logs b, b.c
tmp = o.b.d[0] // 3 logs b, b.d, b.d.0