【发布时间】:2017-08-31 08:54:46
【问题描述】:
我正在通过 Google Chrome 版本 57.0.2987.133 运行以下脚本:
var loggingProxyHandler = {
"get" : function(targetObj, propName, receiverProxy) {
let ret = Reflect.get(targetObj, propName, receiverProxy);
console.log("get("+propName.toString()+"="+ret+")");
return ret;
},
"set" : function(targetObj, propName, propValue, receiverProxy) {
console.log("set("+propName.toString()+"="+propValue+")");
return Reflect.set(targetObj, propName, propValue, receiverProxy);
}
};
function onRunTest()
{
let m1 = new Map();
let p1 = new Proxy(m1, loggingProxyHandler);
p1.set("a", "aval"); // Exception thrown from here
}
onRunTest();
NOTE: Requires a browser supporting ES2015's Proxy
运行时,我看到处理程序的 get 陷阱被调用以返回 Map 的 set 函数 然后我收到以下错误:
"Uncaught TypeError: Method Map.prototype.set called on incompatible receiver [object Object]"
at Proxy.set (native)
...
我尝试从 loggingProxyHandler 中删除陷阱函数(使其成为空对象),但仍然收到相同的错误。
我的理解是应该能够为所有原生 ES5 和 ES2015 javascript 对象生成代理对象。 Array 似乎在同一个代理处理程序下运行良好。
我误解了规格吗?
我的代码缺少什么吗?
Chrome 中是否存在已知错误? (我进行了搜索,发现 Chrome 在这个主题上没有任何缺陷。)
【问题讨论】:
-
听起来您实际上想要做的是覆盖(拦截)
set和get调用,而不是通过代理路由所有属性访问? -
明确一点:不要使用
Proxy拦截异常行为,这超出了正常的Object语义。改用子类化。 -
为了更清楚地说明:在某些情况下您可能需要最终代理地图,尤其是当您不拥有原始对象图但希望观察它的任何更改时。
标签: javascript google-chrome dictionary proxy