例如,如果我有这个处理程序/代理(来自MDN example)...
Traceback (most recent call last):
File "C:/Users/Kane/Desktop/huh.py", line 2, in <module>
image_file = Image.open("James.png")
File "C:\Python27\lib\site-packages\PIL\Image.py", line 1952, in open
fp = __builtin__.open(fp, "rb")
IOError: [Errno 2] No such file or directory: 'James.png'
是否可以通过某种方式探测代理var handler = {
get: function(target, name){
return name in target?
target[name] :
37;
}
};
var p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37
,从而使我能够获取p
个对象。
有些事情:
handler
显然,处理程序中设置的各种陷阱仍然是已知的#34;到代理,但有一个明确的方式从代理本身返回/处理程序?如果是这样,怎么样?
目前我没有具体的用例,但如果您想在已经拥有代理后动态更改处理程序/陷阱,我可以看到这很有用。
答案 0 :(得分:10)
ECMAScript无法访问内部[[ProxyHandler]]和[[ProxyTarget]]插槽。
某些实现可能会提供一些非标准方法,但不要将其视为理所当然。
例如,在Firefox特权代码上,您可以使用
知道对象是否是代理Components.utils.isProxy(object);
我建议实现类似的方法来公开[[ProxyHandler]]和[[ProxyTarget]]。他们告诉我在Debugger.Object
而不是Components.utils
中实施它们。
当补丁降落时,可以使用
之类的东西Components.utils.import('resource://gre/modules/jsdebugger.jsm');
var Cc = Components.classes;
// Add a debugger to a new global
var global = new Components.utils.Sandbox(
Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal),
{ freshZone: true }
);
addDebuggerToGlobal(global);
var dbg = new global.Debugger().addDebuggee(this);
// Create a debugger object of your object, and run proxy getters
var dbgObj = dbg.makeDebuggeeValue(object);
if(dbgObj.isProxy) { // a boolean
dbgObj.proxyHandler.unsafeDereference(); // the [[ProxyHandler]]
dbgObj.proxyTarget.unsafeDereference(); // the [[ProxyTarget]]
}
答案 1 :(得分:2)
添加&#34;特殊&#34;自描述符属性为getOwnPropertyDescriptor
const target = {
//Fns ..
//Props ...
};
const handler = {
getOwnPropertyDescriptor(target, prop) {
if(prop == "[[handler]]"){
return { configurable: true, enumerable: true, value: this };
}
return undefined;
},
prop1: 'abcd'
};
const proxy = new Proxy(target, handler);
console.log(Object.getOwnPropertyDescriptor(proxy, '[[handler]]').value.prop1);
&#13;
答案 2 :(得分:0)
如果您想在拥有代理后动态更改处理程序/陷阱,我会觉得这很有用
如果只想在您已经可以访问的(代理)对象上添加处理程序,,则可以通过创建一个新的代理来实现此目的,该代理可以处理要更改的特定陷阱,例如:
let newProxyWithDifferentGet = new Proxy(originalProxy, {
get: (target, key){ ... }
}
如果您想访问原始代理的目标:
如果您是原始代理的作者,则在构造它时可以执行以下操作:
let openedProxy = new Proxy(Object.assign(target, {
_originalHandler: handler,
_originalTarget: target
}), handler)
如果您不是作者,那么原始目标是否应为用户所用,取决于编写原始代理的人。如果您不同意该作者的封装方式,则这是一个社会问题,而不是技术问题,并且这不是ES6代理服务器特有的或不是唯一的。如果您使用的是开放源代码,请向上游发送PR,以说明您认为原始目标应该对用户可用的原因,或者只是将他们的代码与您的更改进行合并并使用,然后将他们的更新合并到原始存储库中。