Serializing an ES6 Class Object as JSON

class MyClass {
  constructor() {
    this.foo = 3
  }
}

var myClass = new MyClass()

I would like to serialize an object myClassfor json.

One simple way I can think of is that each member is actually a javascript object (array, etc.). I think I can support a variable to hold member variables.

this.prop.foo = this.foo etc.

I expected to find a library toJSON/fromJSONfor class objects, since I used them with other languages ​​like swift / java, but could not find them for javascript.

Maybe the construction of the class is too new, or what I ask can be somehow easily achieved without a library.

+11
source share
6 answers

, JS, JSON.stringify:

JSON.stringify(yourObject);

class MyClass {
  constructor() {
    this.foo = 3
  }
}

var myClass = new MyClass()

console.log(JSON.stringify(myClass));
Hide result

, , stringify , toJSON. , JSON, toJSON .

+7

, , , , "" .

, .

, , , , .


class Serializer{
    constructor(types){this.types = types;}
    serialize(object) {
        let idx = this.types.findIndex((e)=> {return e.name == object.constructor.name});
        if (idx == -1) throw "type  '" + object.constructor.name + "' not initialized";
        return JSON.stringify([idx, Object.entries(object)]);
    }
    deserialize(jstring) {
        let array = JSON.parse(jstring);
        let object = new this.types[array[0]]();
        array[1].map(e=>{object[e[0]] = e[1];});
        return object;
    }
}

class MyClass {
    constructor(foo) {this.foo = foo;}
    getFoo(){return this.foo;}
}

var serializer = new Serializer([MyClass]);

console.log(serializer.serialize(new MyClass(42)));
//[0,[["foo",42]]]

console.log(serializer.deserialize('[0,[["foo",42]]]').getFoo());
//42
Hide result

, , .

+6

, ( ):

https://github.com/typestack/class-transformer

:

plainToClass() -> json obj to class
classToPlain() -> class to json obj

,

+2

. , .

:

class Serializer
{
  constructor(types){
    this.types = types;
  }

  markRecursive(object)
  {
    // anoint each object with a type index
    let idx = this.types.findIndex(t => {
      return t.name === object.constructor.name;
    });
    if (idx !== -1)
    {
      object['typeIndex'] = idx;

      for (let key in object)
      {
        if (object.hasOwnProperty(key) && object[key] != null)
          this.markRecursive(object[key]);
      }
    }
  }

  cleanUp(object)
  {
    if (object.hasOwnProperty('typeIndex')) {
      delete object.typeIndex;
      for (let key in object) {
        if (object.hasOwnProperty(key) && object[key] != null) {
          console.log(key);
          this.cleanUp(object[key]);
        }
      }
    }
  }

  reconstructRecursive(object)
  {
    if (object.hasOwnProperty('typeIndex'))
    {
      let type = this.types[object.typeIndex];
      let obj = new type();
      for (let key in object)
      {
        if (object.hasOwnProperty(key) && object[key] != null) {
          obj[key] = this.reconstructRecursive(object[key]);
        }
      }
      delete obj.typeIndex;
      return obj;
    }
    return object;
  }

  clone(object)
  {
    this.markRecursive(object);
    let copy = JSON.parse(JSON.stringify(object));
    this.cleanUp(object);
    return this.reconstructRecursive(copy);
  }
}

: (, this.types) this.types typeIndex. , typeIndex, , .

0

esserializer . JavaScript " " // ..

, serialize():

const ESSerializer = require('esserializer');
let serializedString = ESSerializer.serialize(anObject);

serialize(): .

To deserialize from a string, simply call the method deserialize(), passing all the classes involved as a parameter:

const ESSerializer = require('esserializer');
const ClassA = require('./ClassA');
const ClassB = require('./ClassB');
const ClassC = require('./ClassC');

let deserializedObj = ESSerializer.deserialize(serializedString, [ClassA, ClassB, ClassC]);

Internal mechanism deserialize(): manually recursively composes an object with information about its prototype.

0
source

This is easy if you do not mind passing the class definition to decoding.

// the code
const encode = (object) => JSON.stringify(Object.entries(object))

const decode = (string, T) => {
  const object = new T()
  JSON.parse(string).map(([key, value]) => (object[key] = value))
  return object
}

// test the code
class A {
  constructor(n) {
    this.n = n
  }

  inc(n) {
    this.n += n
  }
}

const a = new A(1)
const encoded = encode(a)
const decoded = decode(encoded, A)
decoded.inc(2)
console.log(decoded)
Run codeHide result
0
source

Source: https://habr.com/ru/post/1658600/


All Articles