Для приложений Javascript более богатая сериализация данных, чем у обычного JSON? - PullRequest
2 голосов
/ 29 апреля 2019

JSON отлично работает для простых вещей, но иногда мои данные имеют больше типов, чем JSON может обработать.Например: Sets, UUIDs, Symbols, Dates, байтовые массивы и т. Д. Нужно ли вручную преобразовывать их в JSON и из него, или есть библиотека или стандартный способ сделать это?

Я создаю веб-приложение с Node.js на сервере и достаточным количеством Javascript / Typescript в браузере для отправки и получения данных.

1 Ответ

1 голос
/ 29 апреля 2019

Как я упоминаю в комментариях, я не знаю ни одной библиотеки, которая делает это из коробки.

Но простое кодирование / декодирование, чтобы сделать это автоматически, довольно легко сделать, ниже я в основном помечаю ключи объектов некоторой простой информацией о типе, например. «Date», «Sym», «Str» и т. Д. Конечно, это еще не все, вы можете расширить их на любое количество типов, но, надеюсь, это станет отправной точкой.

Также должно быть просто сделать эту сериализацию глубокой, я оставил это здесь для простоты. Но если вам нужна вложенная сериализация и вам нужна помощь, просто дайте нам знать.

const symbol1 = Symbol("symbol1");

//for symbols were going to need a lookup
//using a named symbol here would be best
//but remember Symbol("1") === Symbol("1") is false
const symLookup = {
  [symbol1.toString()] : symbol1
};

function encode(src) {
  return JSON.stringify(Object.entries(src).reduce(
    (a, [k, v]) => {
      if (v instanceof Date) {
        k = 'Date_' + k;
        v = v.getTime();
      } else if (v instanceof Set) {
        k = 'Set_' + k;
        v = Array.from(v);
      } else if (typeof v === 'string') {
        k = 'Str_' + k;
      } else if (typeof v === 'symbol') {
        k = 'Sym_' + k;
        v = v.toString()
      } else throw new Error("Not yet implemented");
      a[k] = v;
      return a;
    }, {}));
}

function decode(src) {
  const o = JSON.parse(src);
  const reS = /^(.+)_(.+)$/;
  return Object.entries(o).reduce(
    (a, [k, v]) => {
      const [, tp, k2] = reS.exec(k);
      if (tp === 'Date') v = new Date(v);
      else if (tp === 'Set') v = new Set(v);
      else if (tp === 'Sym') v = symLookup[v];
      a[k2] = v;
      return a;
    }, {});
}


const data = {
  theDate: new Date(),
  aSet: new Set([1,2,3]),
  justAString: "Hello there",
  sym: symbol1
}

console.log('src data = '); console.log(data);
var encoded = encode(data);
console.log('encoded data = '); console.log(encoded);
var decoded = decode(encoded);
console.log('decoded data = '); console.log(decoded);
<p>Look in browsers console to see results..</p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...