15

たとえば、このハンドラー/プロキシがある場合 ( 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

オブジェクト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){ ...}

明らかに、ハンドラーに設定されたさまざまなトラップはプロキシに「認識」されていますが、プロキシ自体からそれら/ハンドラーを返す明確な方法はありますか? もしそうなら、どのように?

現時点では、これに関する特定の使用例はありませんが、既にプロキシを取得した後でハンドラー/トラップを動的に変更したい場合に、これが役立つことがわかります。

4

3 に答える 3

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]]
}
于 2016-07-14T23:20:40.430 に答える
6

「特別な」自己記述子プロパティを 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);

于 2018-06-19T02:32:27.250 に答える