Best way to serialize/unserialize objects in JavaScript? Best way to serialize/unserialize objects in JavaScript? javascript javascript

Best way to serialize/unserialize objects in JavaScript?


JSON has no functions as data types. You can only serialize strings, numbers, objects, arrays, and booleans (and null)

You could create your own toJson method, only passing the data that really has to be serialized:

Person.prototype.toJson = function() {    return JSON.stringify({age: this.age});};

Similar for deserializing:

Person.fromJson = function(json) {    var data = JSON.parse(json); // Parsing the json string.    return new Person(data.age);};

The usage would be:

var serialize = p1.toJson();var _p1 = Person.fromJson(serialize);alert("Is old: " + _p1.isOld());

To reduce the amount of work, you could consider to store all the data that needs to be serialized in a special "data" property for each Person instance. For example:

function Person(age) {    this.data = {        age: age    };    this.isOld = function (){        return this.data.age > 60 ? true : false;    }}

then serializing and deserializing is merely calling JSON.stringify(this.data) and setting the data of an instance would be instance.data = JSON.parse(json).

This would keep the toJson and fromJson methods simple but you'd have to adjust your other functions.


Side note:

You should add the isOld method to the prototype of the function:

Person.prototype.isOld = function() {}

Otherwise, every instance has it's own instance of that function which also increases memory.


I wrote serialijse because I faced the same problem as you.

you can find it at https://github.com/erossignon/serialijse

It can be used in nodejs or in a browser and can serve to serialize and deserialize a complex set of objects from one context (nodejs) to the other (browser) or vice-versa.

var s = require("serialijse");var assert = require("assert");// testing serialization of a simple javascript object with datefunction testing_javascript_serialization_object_with_date() {    var o = {        date: new Date(),        name: "foo"    };    console.log(o.name, o.date.toISOString());    // JSON will fail as JSON doesn't preserve dates    try {        var jstr = JSON.stringify(o);        var jo = JSON.parse(jstr);        console.log(jo.name, jo.date.toISOString());    } catch (err) {        console.log(" JSON has failed to preserve Date during stringify/parse ");        console.log("  and has generated the following error message", err.message);    }    console.log("");    var str = s.serialize(o);    var so = s.deserialize(str);    console.log(" However Serialijse knows how to preserve date during serialization/deserialization :");    console.log(so.name, so.date.toISOString());    console.log("");}testing_javascript_serialization_object_with_date();// serializing a instance of a classfunction testing_javascript_serialization_instance_of_a_class() {    function Person() {        this.firstName = "Joe";        this.lastName = "Doe";        this.age = 42;    }    Person.prototype.fullName = function () {        return this.firstName + " " + this.lastName;    };    // testing serialization using  JSON.stringify/JSON.parse    var o = new Person();    console.log(o.fullName(), " age=", o.age);    try {        var jstr = JSON.stringify(o);        var jo = JSON.parse(jstr);        console.log(jo.fullName(), " age=", jo.age);    } catch (err) {        console.log(" JSON has failed to preserve the object class ");        console.log("  and has generated the following error message", err.message);    }    console.log("");    // now testing serialization using serialijse  serialize/deserialize    s.declarePersistable(Person);    var str = s.serialize(o);    var so = s.deserialize(str);    console.log(" However Serialijse knows how to preserve object classes serialization/deserialization :");    console.log(so.fullName(), " age=", so.age);}testing_javascript_serialization_instance_of_a_class();// serializing an object with cyclic dependenciesfunction testing_javascript_serialization_objects_with_cyclic_dependencies() {    var Mary = { name: "Mary", friends: [] };    var Bob = { name: "Bob", friends: [] };    Mary.friends.push(Bob);    Bob.friends.push(Mary);    var group = [ Mary, Bob];    console.log(group);    // testing serialization using  JSON.stringify/JSON.parse    try {        var jstr = JSON.stringify(group);        var jo = JSON.parse(jstr);        console.log(jo);    } catch (err) {        console.log(" JSON has failed to manage object with cyclic deps");        console.log("  and has generated the following error message", err.message);    }    // now testing serialization using serialijse  serialize/deserialize    var str = s.serialize(group);    var so = s.deserialize(str);    console.log(" However Serialijse knows to manage object with cyclic deps !");    console.log(so);    assert(so[0].friends[0] == so[1]); // Mary's friend is Bob}testing_javascript_serialization_objects_with_cyclic_dependencies();


I am the author of https://github.com/joonhocho/seri.

Seri is JSON + custom (nested) class support.

You simply need to provide toJSON and fromJSON to serialize and deserialize any class instances.

Here's an example with nested class objects:

import seri from 'seri';class Item {  static fromJSON = (name) => new Item(name)  constructor(name) {    this.name = name;  }  toJSON() {    return this.name;  }}class Bag {  static fromJSON = (itemsJson) => new Bag(seri.parse(itemsJson))  constructor(items) {    this.items = items;  }  toJSON() {    return seri.stringify(this.items);  }}// register classesseri.addClass(Item);seri.addClass(Bag);const bag = new Bag([  new Item('apple'),  new Item('orange'),]);const bagClone = seri.parse(seri.stringify(bag));// validatebagClone instanceof Bag;bagClone.items[0] instanceof Item;bagClone.items[0].name === 'apple';bagClone.items[1] instanceof Item;bagClone.items[1].name === 'orange';

Hope it helps address your problem.