Как получить обработчик прокси из объекта прокси?

Например, если у меня есть этот обработчик / прокси (изПример 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){ ...}

Очевидно, что различные ловушки, установленные в обработчике, все еще «известны» прокси-серверу, но существует ли четкий способ вернуть их / обработчик из самого прокси? Если да, то как?

У меня нет конкретного варианта использования для этого на данный момент, но я мог бы увидеть, что это полезно, если вы хотите динамически изменить обработчик / ловушки после того, как у вас уже есть прокси.

 Steve Ladavich15 июл. 2016 г., 17:53
@ Берджи, мне странно, что стандартная точка «прокси» будет обязательной. Я думаю, что в идеале создатель прокси должен объявить прокси общедоступным / открытым или частным, даже если в 95% случаев «правильный» ответ заключается в том, что потребители не могут его осмотреть / дополнить.
 Bergi15 июл. 2016 г., 01:24
Суть прокси в том, что потребители не имеют права проверять это так, они должны относиться к нему как к любому другому объекту. Если вы являетесь создателем прокси-сервера, довольно просто сохранить ссылку наhandler
 Bergi16 июл. 2016 г., 12:22
Да, именно, создатель прокси может выставить обработчик - просто сделайтеnew Proxy({__handler__: handler}, handler) если тебе это нужно Он не выставлен по умолчанию, потому что в 95% случаев он не нужен.
 Bergi15 июл. 2016 г., 01:21
Вы должны спросить любезно. Если прокси-сервер определяет__handler__ собственность, она ответит на ваш запрос.
 Steve Ladavich16 июл. 2016 г., 20:13
@ Берги, ах, теперь я понимаю, что ты имеешь в виду. Это не было очевидно для меня из вашего первоначального комментария. Пожалуйста, рассмотрите возможность добавления / расширения ваших мыслей в качестве ответа. Я думаю, что то, что вы говорите / намекаете на то, что прокси скрыты преднамеренно, является проницательным, в то время как ваше обходное решение, которое делает это возможным, очень актуально и, вероятно, очень применимо для всех, кому это интересно.

Ответы на вопрос(3)

Решение Вопроса

]] и [[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]]
}
 Pacerier12 сент. 2017 г., 20:44
А как насчет Chrome?

если вы хотите динамически изменять обработчик / ловушки после того, как у вас уже есть прокси

Если вы просто хотите добавить обработчики поверх (прокси) объекта, к которому у вас уже есть доступ: этого можно достичь, создав новый прокси-сервер, который обрабатывает определенные ловушки, которые вы хотите изменить, например:

let newProxyWithDifferentGet = new Proxy(originalProxy, {
  get: (target, key){ ... }
}

Если вы хотите получить доступ коригинал Цель прокси:

Если вы являетесь автором оригинального прокси-сервера, вы можете просто сделать что-то вроде этого при создании:

let openedProxy = new Proxy(Object.assign(target, {
  _originalHandler: handler,
  _originalTarget: target
}), handler)

Если вы не автор, то, должна ли эта первоначальная цель быть доступной для пользователей, решит тот, кто написал этот оригинальный прокси. Если вы не согласны с этим автором по поводу их инкапсуляции,это социальная проблема, а не техническая, и это не является специфическим или уникальным для прокси ES6. Если вы потребляете код с открытым исходным кодом, отправьте PR-апстрим, объясняющий, почему вы считаете, что исходная цель должна быть доступна пользователям, или просто раскошелите их код с вашими изменениями и используйте его, объединяя их обновления с исходным репо по мере продвижения.

Добавьте «специальное» свойство самоописателя в 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);

Ваш ответ на вопрос