如何从代理对象获取代理的处理程序?

时间:2016-07-14 23:04:38

标签: javascript ecmascript-6 es6-proxy

例如,如果我有这个处理程序/代理(来自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;到代理,但有一个明确的方式从代理本身返回/处理程序?如果是这样,怎么样?

目前我没有具体的用例,但如果您想在已经拥有代理后动态更改处理程序/陷阱,我可以看到这很有用。

3 个答案:

答案 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

&#13;
&#13;
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;
&#13;
&#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,以说明您认为原始目标应该对用户可用的原因,或者只是将他们的代码与您的更改进行合并并使用,然后将他们的更新合并到原始存储库中。