сопоставить ключи JSON с объектом Javascript - PullRequest
1 голос
/ 01 октября 2019

Мне нужно разобрать файл json в объект javascript. Я использую GCC (Closure Compiler), который может искажать имена моих объектов, поэтому мне нужно ссылаться на ключи json как на строки при импорте или экспорте файла json.

то есть импорт:

var jsonobj = JSON.parse(json_object_text);
myobj.member1 = jsonobj['Key 1'];
myobj.member2 = jsonobj['Key 2'];

и экспорт:

jsonobj['Key 1'] = myobj.member1;
jsonobj['Key 2'] = myobj.member2;
var json_object_text = JSON.stringify(jsonobj);

Но делать это утомительно. И я хотел бы определить ключи как текстовые строки только один раз.

Поэтому я попытался определить постоянный объект, который является своего рода отображением из объекта javascript в схему json.

// Schema definition for import/export of confc.json.
/** @const */ var dbs = {
    $schema: '$schema',
    $seq: '$seq',
    channel: {
      key: 'chan',
      id: 'id',
      name: 'txt',
      value: 'val'
    }
}

Но тогда мне все равно пришлось сделать утомительную функцию импорта / экспорта:

    export_db: function (db) {
      return db && {
        [dbs.$schema]: db.$schema,
        [dbs.$seq]: db.$seq,
        [dbs.channel.key]: db.channel.map(function (e, i) {
          var s = dbs.channel; // schema object
          return {
            [s.id]: util.toInt(e.id),
            [s.name]: e.name,
            [s.value]: e.value
          };
        }),
    import_db: function (js) {
      js = js || {};
      // wrapper for .map() function which works if array is undefined.
      function dbmap(arr_in, func) {
        arr_in = arr_in || [];
        return arr_in.map(func);
      }
      return {
        $schema: js[dbs.$schema],
        $seq: js[dbs.$seq],
        channel: dbmap(js[dbs.channel.key], function (e, i) {
          var s = dbs.channel;
          return {
            id: e[s.id],
            name: e[s.name],
            value: e[s.value]
          };
        }),

Кажется, это работает нормально, но кто-то, пожалуйста, покажет мне более чистый способчтобы сделать это?

Я хотел бы использовать прототип / конструктор объекта, как в примерах , приведенных здесь . Но я не вижу примеров, которые бы учитывали, как GCC может манипулировать именами объектов. Также у меня есть вложенные объекты (без функций, только текст и цифры).

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Если источник данных является внешним, или если вам нужно обмениваться данными извне, то способ, которым Closure поддерживает это, посредством externs и @export аннотаций . Добавленные пользователем externs являются отличным источником для примеров.

Это может выглядеть так в зависимости от вашей среды;

// externs / config.js

/**
 * @typedef {{
 *   foo: (string|undefined),
 *   [...]
 * }}
 */
Bar.Config;

/**
 * @typedef {{
 *   bar: (string|undefined),
 *   [...]
 * }}
 */
Bar.Output;

// main.js

/**
 * @param {Bar.Config} config 
 * @return {Bar.Output}
 */
const bar = function(config) {
//  [...]
  return output;
};

0 голосов
/ 02 октября 2019

JSON по сути уже находится в формате объекта (JSON = JavaScript Object Notation).

var jsonobj = JSON.parse(json_object_text) должно быть всем, что вам нужно для доступа к объекту, который вы только что создали, который называется jsonobj. Любые члены этого объекта доступны так же, как если бы вы определили их в конструкторе или где-либо еще. Есть ли причина, по которой вы переназначаете его на другой объект?

...