假设我有一个对象var obj = {}
。我希望稍后调用一个处理程序,检索任何字段; obj.b
。
我知道代理,
var obj = {};
var proxy = new Proxy(obj, {
get(obj, prop) {
console.log('get', prop)
return Reflect.get(obj, prop);
}
})
但是,这只会在通过代理proxy.b
访问属性时记录,否则将无法记录obj.b
。
我也知道使用defineProperty
将getter放在obj
的所有键上。但是,这将不会处理添加getter后添加到obj
的新字段。
也许如果可以重新实现代理,那么应该可以将处理程序添加到原始obj
而不是proxy
。我已经尝试过调查代理对象,但它似乎是在内部实现的。 new Proxy({},{})
包含属性[[Handler]]
,[[Target]]
和[[IsRevoked]]
,但我无法访问或查看这些对象; proxy['[[Handler]]']
返回undefined
。我在想是否可以将这些处理程序和目标字段自己添加到obj
,而不是创建单独的代理对象,然后我可以使obj
像代理一样。
我已经阅读了MDN的代理,defineProperty和处理程序的文档,甚至是http://exploringjs.com/es6/ch_proxies.html。我同样遇到了多个堆栈溢出帖子,实现了类似但不完全的东西。
---编辑,我的用例(如果这比我的目标解决方案更清晰)---
我正在将source
对象绑定到dom elmenets。例如,您更改source.text
,并且dom上的一些文本也会更改。为此,source是一个代理,带有一个set handler来适当地更新dom。但是,要允许源上的嵌套字段,我必须在source.obj.text
更改时进行处理。为此,我的源代理也有一个get hander,它也返回一个具有类似set和get处理程序的代理。以下代码段:
let createProxy = (obj, handlers) => new Proxy(obj, {
get: (target, prop) => {
let got = Reflect.get(target, prop);
return typeof got === 'object' && got !== null ? createProxy(got, handlers && handlers[prop]) : got;
},
set: (target, prop, value) => {
if (Reflect.get(target, prop) !== value) {
Reflect.set(target, prop, value);
handlers && propogateHandlerDown(handlers);
}
return true;
}
});
这由let source = createProxy({}, ...)
在内部使用,然后用户返回source
。这通常很好。当用户不使用源时,问题就出现了,例如
let obj = {};
source.list = [obj];
source.list[0].text = 'this works fine';
obj.text = 'this does not work, as obj is not a proxy';