как мне превратить прокси-сервер ES6 обратно в простой объект (POJO)?

Я использую библиотеку, которая превращает вещи в прокси-объекты ES6, и другую библиотеку, которая, как я думаю, задыхается, потому что я передаю ей один из этих (я знаю, мой код — пародия), и я не мог понять, как для unProxy объекта Proxy.

Но я просто был тупым. Прокси могут все!


person Sigfried    schedule 01.11.2018    source источник
comment
Почему библиотека давится вашим прокси? Пожалуйста, опубликуйте (соответствующую часть) код библиотеки и вашего прокси, чтобы мы могли помочь вам исправить ваши обработчики.   -  person Bergi    schedule 01.11.2018


Ответы (7)


Пробовал использовать JSON.parse(JSON.stringify(proxyObj)), но это удаляет все, что не может быть преобразовано в строку (например, классы, функции, обратный вызов и т. д.), что не подходит для моего варианта использования, поскольку у меня есть объявления некоторых функций обратного вызова в моем объекте, и я хочу видеть их как часть моего объекта. Однако я обнаружил, что использование функции Lodash cloneDeep делает очень хорошую работу по преобразованию прокси-сервера. объект в POJO, сохраняя при этом структуру объекта.

convertProxyObjectToPojo(proxyObj) {
  return _.cloneDeep(proxyObj);
}
person ghiscoding    schedule 21.02.2020
comment
Мне это нравится, так как я обычно доверяю lodash, и он скрывает все запутанные вещи. Я больше не использую ту библиотеку, которая меня смущала, поэтому я не могу проверить разные ответы. Если кто-то возражает против того, чтобы я выбрал этот ответ в качестве официального, дайте мне знать, и я вернусь. - person Sigfried; 24.02.2020

Я нахожу хак. В моем случае я не могу контролировать создание прокси (наблюдаемые значения mobx). Итак, решение:

JSON.parse(JSON.stringify(your.object))
person Alex Park    schedule 31.01.2019
comment
умный :) иногда все может быть так просто, спасибо! - person Basti; 16.07.2019
comment
Не приведет ли это к потере некоторых вещей? Кажется, людям это нравится. - person Sigfried; 13.03.2020
comment
@Sigfried Зигфрид хорошо, как было сказано в принятом ответе, он теряет некоторые вещи, но я думаю, что это наиболее распространенный случай, когда у вас нет таких свойств в вашем объекте. Я думаю, что это хорошо только как инструмент отладки, по крайней мере, я использовал его только для этой цели. JSON.stringify({ ключ: не определено}); JSON.stringify({key: Symbol() }); JSON.stringify({key: function(){} }); // все будет преобразовано только в {} - person Alex Park; 16.03.2020

pp = new Proxy(
   {a:1},
   {
      get: function(target, prop, receiver) { 
             if(prop==='target') return target 
           }
   }
)

Но это будет работать только в том случае, если вы можете контролировать создание прокси. А оказывается все еще проще:

pojo = Object.assign({}, proxyObj) // won't unwrap nested proxies though

Для читателей, которым может понравиться этот ответ, новый ответ Дэвида Гилбертсона может быть лучше. Я лично предпочитаю lodash clonedeep. И самым популярным кажется JSON.parse(JSON.stringify(...))

person Sigfried    schedule 01.11.2018
comment
Это приводит к {a: undefined}, а не {a: 1}, если обработчик get все еще существует. В противном случае ({...proxyObj}) будет еще короче. . - person Sebastian Simon; 01.11.2018
comment
Вашему обработчику get нужен случай else, когда он ведет себя нормально (т. е. Reflect.get) на свойствах, отличных от target. - person Bergi; 01.11.2018
comment
Если кто-то из вас захочет добавить ответ, я буду рад удалить свой неудачный ответ. - person Sigfried; 02.11.2018

Как насчет использования оператора расширения?

 const plainObject = { ...proxyObject };
person Cycododge    schedule 17.11.2020

Спасибо @sigfried за ответ, это именно то, что я искал!

Вот немного более подробная версия, где используется Symbol, чтобы избежать конфликтов с реальными именами реквизита.

const original = {foo: 'bar'};

const handler = {
  get(target, prop) {
    if (prop === Symbol.for('ORIGINAL')) return target;

    return Reflect.get(target, prop);
  }
};

const proxied = new Proxy(original, handler);

console.assert(original !== proxied);

const unproxied = proxied[Symbol.for('ORIGINAL')];

console.assert(original === unproxied);
person David Gilbertson    schedule 13.03.2020
comment
Спасибо. Я отредактировал свой, чтобы отослать людей к этому тогда. Было бы неплохо, если бы кто-нибудь обобщил и сравнил плюсы и минусы разных ответов. Может быть, когда-нибудь я это сделаю, если больше никто этого не сделает. - person Sigfried; 13.03.2020

Обычно для этого вы используете mobx util toJS().

import { observable, toJS } from "mobx";

const observed = observable({ foo: 'bar' })

const obj = toJS(observed)
person Gabiriele Lalasava    schedule 07.11.2020

В конструкторе непроксируемых объектов добавьте this.self=this

Затем убедитесь, что ваш обработчик get позволяет вернуть свойство self, и все готово. proxiedMyObj.self===myObj //returns true

person Bikibird    schedule 23.08.2019