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

Ste*_*ich 12 javascript ecmascript-6 es6-proxy

例如,如果我有这个处理程序/代理(来自MDN示例)...

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
Run Code Online (Sandbox Code Playgroud)

是否可以探测代理,p以某种方式允许我获取handler对象.

有点像:

p.__handler__   // returns handler object -> Object {get: handler.get(), set: handler.set(), ...}
p.__handler__.get  // returns get prop/fn of handler -> function(target, name){ ...}
Run Code Online (Sandbox Code Playgroud)

显然,在处理程序中设置的各种陷阱仍然对代理"已知",但有一种明确的方式从代理本身返回它们/处理程序吗?如果是这样,怎么样?

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

Ori*_*iol 10

ECMAScript无法访问内部[[ProxyHandler]]和[[ProxyTarget]]插槽.

某些实现可能会提供一些非标准方法,但不要将其视为理所当然.

例如,在Firefox特权代码上,您可以知道对象是否是使用的代理

Components.utils.isProxy(object);
Run Code Online (Sandbox Code Playgroud)

我提议实现类似的方法来公开[[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]]
}
Run Code Online (Sandbox Code Playgroud)


小智 7

将“特殊”自描述符属性添加到 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);
Run Code Online (Sandbox Code Playgroud)