Serialization

Since JOII 3.2.0, instantiated classes can be serialized/deserialized to and from a JSON string using the built-in serialize method and the static deserialize method. By default, all public properties are serializable.

To serialize a class, use the serialize method on an instantiated class. For example:

require('./dist/joii');

// Create a base class to demonstrate inheritance.
var Base = Class('Base', {
    'public string base': "Drop it!"
});

// Create a class with a few public properties.
var MyClass = Class('MyClass', {"extends": Base}, {
    'public string foo': 'Hello',
    'public string bar': 'World',

    // this constructor will be called from deserialize, prior to restoring the data
    constructor: function () {
        this.foo = "Hello";
    },
});

var mc = new MyClass();

mc.setBar('People!');
mc.setBase('Right now!');

var serialized = mc.serialize();
console.log(serialized);
// >> {"__joii_type":"MyClass","foo":"Hello","bar":"People!","base":"Right now!"}

To deserialize a JSON string back into an instantiated class, use the deserialize function which can be called on your class declaration, like so:

var mc2 = MyClass.deserialize(serialized);

console.log(mc2.getBase()); // Right now!

Note that if the deserialized class has a constructor which takes an object (declared as 'construct(object)'), or a catch-all constructor (declared as just 'construct'), it will be called upon instantiation. Properties saved in the serialized string are put back into their original properties after the constructor executes, once the class is instantiated.

Private / Protected properties

By default, private and protected properties are not serialized when calling the serialize() method on an instantiated class. You can add them by adding the serializable modifier to the property declaration.


var MyClass = Class('MyClass', {
    'private serializable string some_name': null,

    // this constructor will NOT be called from deserialize, since it specifies no parameters
    'constructor()': function () {
        this.some_name = "John Doe";
    },
    // this constructor will NOT be called from deserialize, since it specifies that it takes a string
    'constructor(string)': function (str) {
        this.some_name = str;
    },
    // this constructor WILL be called from deserialize, since it specifies that it takes an object
    'constructor(object)': function (obj) {
        if ('__joii_deserialize_object' in obj) {
            // do something to prepare for deserialize
        } else {
            // Deserialize didn't call this, something else called this. Handle custom object.
        }
    },

    'updateName(string)': function (name) {
        this.some_name = name;
    },

    'getName()': function() {
        return this.some_name;
    }
});

var mc = new MyClass();
mc.updateName('Bob Ross');
var serialized = mc.serialize(); // {"__joii_type":"MyClass","some_name":"Bob Ross"}

var mc2 = MyClass.deserialize(serialized);
console.log(mc2.getName()); // Bob Ross.

Don't serialize everything

If you don't wish to serialize a specific property, you can use the notserializable modifier to do so.

var MyClass = Class('MyClass', {
    'public notserializable string foo': 'bar',
    'public                 string bar': 'baz'
});

var mc = new MyClass();
mc.setFoo('Hello');
mc.setBar('World');
var serialized = mc.serialize(); // {"__joii_type":"MyClass","bar":"baz"}

var mc2 = MyClass.deserialize(serialized);
console.log(mc2.getFoo()); // bar
console.log(mc2.getBar()); // World