Как получить цель прокси JavaScript? - PullRequest
0 голосов
/ 29 июня 2018
function createProxy() {
    const myArray = [Math.random(), Math.random()];
    return new Proxy(myArray, {});
}

const myProxy = createProxy();

Как получить доступ к target (который myArray) из myProxy здесь?

Я пробовал много способов. Погуглил много постов в блоге, но не нашел способа получить цель: (

Ответы [ 7 ]

0 голосов
/ 17 марта 2019

Как уже говорилось в других ответах, ловушка для прокси-сервера может быть элегантным решением.

const IDENTITY = Symbol('proxy_target_identity')
const handler = {
  get: (target, property, receiver) => {
    if (property === IDENTITY && target.hasOwnProperty(IDENTITY)) {
      return target
    }
    return Reflect.get(target, property, receiver)
  }
}


function createProxy() {
    const myArray = [Math.random(), Math.random()];
    return new Proxy(myArray, handler);
}

const myProxy = createProxy();
const orignal_target = myProxy[IDENTITY]

Этот пример кода должен быть достаточно надежным:

  • позволяет избежать конфликтов имен свойств, используя Symbol
  • охватывает все сценарии get, используя Reflect.get вместо target[property]
  • работает с наследованием прототипа - в случае, если ваш прокси-сервер в конечном итоге будет использоваться в качестве прототипа, ваш наследник не вернет себя, несмотря на то, что сам на самом деле не был прокси-сервером.
0 голосов
/ 24 марта 2019

Другие ответы дали несколько хороших решений. Вот ответ @ Yuci для классов, в этом случае это так же просто, как определить переменную экземпляра какого-то специального имени. Функция Proxy get возвращает его, как и основная цель.

class Foo {
    constructor() {
        this.__target__ = this;
        return new Proxy(this, {
            get: function (target, name) {
                if (name in target) return target[name];
                // your code here
            }
        });
    }
}

let foo = new Foo();
let target = foo.__target__;
console.log('proxied Foo', foo);
console.log('recovered target', target, target.__target__.__target__);
0 голосов
/ 22 ноября 2018

Как насчет добавления следующей ловушки get:

const handler = {
  get: (target, property, receiver) => {
    if (property === 'myTarget') {
      return target
    }
    return target[property]
  }
}

const myArray = [Math.random(), Math.random()];

function createProxy() {
//     const myArray = [Math.random(), Math.random()];
    return new Proxy(myArray, handler);
}

const myProxy = createProxy();

И вы можете получить цель прокси по myProxy.myTarget:

console.log(myProxy.myTarget) // [0.22089416118932403, 0.08429264462405173]
console.log(myArray === myProxy.myTarget) // true
0 голосов
/ 11 ноября 2018

Существует умный способ сделать это - вы можете добавить ловушку get к прокси и вернуть ей target условно. Вот так ..

let resolveMode = false;  // Switch that controls if getter returns target or prop. 

function resolve(obj) {
    resolveMode = true;  // Turn on our switch
    let target = obj.anything;  // This gets the target not the prop!
    resolveMode = false;  // Turn off the switch for the getter to behave normally
    return target;  // Return what we got!
}

function createProxy() {
    const myArray = [Math.random(), Math.random()];
    return new Proxy(myArray, {
        get: function(target, prop) {
            if (resolveMode) return target;  // This is where the magic happens!
            else return target[prop];        // This is normal behavior..
        }
    });
}

const myProxy = createProxy();
let target = resolve(myProxy);

Помните, что чем больше строк кода вы добавляете в ловушки, тем медленнее становится производительность объекта. Надеюсь, это поможет.

0 голосов
/ 07 ноября 2018

Можно, если целью является объект.

Вам нужно создать функцию в target, чтобы получить ее, вот и все.

Пример:

class AnyClass {
   constructor() {
      this.target = this;

      return new Proxy(this, this);
   }

   get(obj, prop) {
      if (prop in obj)
          return this[prop];

      // your stuff here
   }

   getTarget() {
      return this.target;
   }
}

А потом при звонке:

let sample = new AnyClass;
console.log(sample.getTarget());

Вернет вам цель, как вы ожидаете:)

0 голосов
/ 04 октября 2018

Поскольку прокси содержит объект, вы также можете сделать

Object.keys( my_proxy )

И тогда становится легко найти такую ​​вещь, как Object.keys( my_proxy ).length

0 голосов
/ 25 сентября 2018

Вы можете сделать копию данных, возвращаемых прокси, используя Object.assign():

const target_copy = Object.assign({}, my_proxy);

Это будет работать для всех перечисляемых собственных свойств , существующих на прокси / цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...