This piece of code is from my radlib library, but I'm putting it here because others might benefit from having this in their game, whether or not they want the full RadLib library.
These two functions, Serialize and Deserialize will store/recall JS objects, restoring their prototypes and non-serializable sphere objects. In Serialize, a new property is tacked on to an object: "zztype", it stores the constructor of the object that created it. Deserialize will call that constructor and then proceed to fill in the stored fields. The reason for this is twofold, one, when the object is re-created it becomes an object of the type of it's constructor rather than 'object' (JSON stringify/parse will turn all objects into general JS objects and strip the methods off of them), two, any sphere objects such as images will be reattached since usually they are created in the constructor function and since they are only used for display: we don't tend to store images/fonts/windowstyles, so they don't have to be saved.
Both Serialize and Deserialize do a deep inspection/clone, so nested objects are also affected.
/**
* Serialize(obj : object);
* - Use this to JSON an object; AND preserve the data type.
**/
function Serialize(obj)
{
function Make(obj) {
var o = { zztype: obj.constructor.name };
for (var i in obj) {
if (!(obj[i] instanceof Array) && typeof obj[i] == "object")
o[i] = Make(obj[i]);
else
o[i] = obj[i];
}
return o;
}
return JSON.stringify(Make(obj));
}
/**
* Deserialize(s : string);
* - Use this to parse a JSON object; AND restore the methods.
**/
function Deserialize(s)
{
function Make(o) {
var obj = new this[o.zztype]();
for (var i in o) {
if (!(o[i] instanceof Array) && o[i] typeof "object")
obj[i] = Make(o[i]);
else
obj[i] = o[i];
}
delete obj.zztype;
return obj;
}
return Make(JSON.parse(s));
}
Therefore, you can now make a class like so:
function Item() {
this.image = LoadImage("dagger.png"); // an image... which can't be saved to file...
this.damage = 5; // this however can; even with JSON.
}
// but this method will be stripped during JSON creation
Item.prototype.swing = function() {
Print("Did " + this.damage + " damage!");
}
var item = new Item();
item.damage += 2; // I upgraded it!!
// serialization keeps an object, well the same object!
var s = Serialize(item);
File.save("item", s); // now I saved it to file!
var o = File.recall("item", "");
item = Deserialize(o);
item.swing(); // prints "Did 7 damage!"
item instanceof Item // returns true
This is great for games where the inventory changes and the items must each be saved. Or other properties such as player stats, and world variables, etc. Have fun!
(edited for proper highlighting ~neo)