Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come JSON can't save object's functions?

In my game, I save the current state by converting all the objects to JSON and then saving that to a file. Some objects, like enemies, have functions on them, but JSON can't save functions! Is there an alternative or a solution?

like image 446
corazza Avatar asked Oct 31 '11 15:10

corazza


2 Answers

var Enemy = {
  toJSON: function () {
    // pack it up
  },
  fromJSON: function (json) {
    // unpack it.
  },
  /* methods */
};

var e = Object.create(Enemy);
var json = JSON.stringify(e);
var same_e = Enemy.fromJSON(json);

the .toJSON method is a standard interface of JSON.stringify it will look this method and call it if it exists, it will stringify the returned object.

The .fromJSON method is just a named constructor for your Enemy object.

Concrete example JSfiddle

var Enemy = {
  constructor: function(name, health) {
    this.health = health || 100;
    this.name = name;
  },
  shootThing: function (thing) { },
  move: function (x,y) { },
  hideBehindCover: function () {},
  toJSON: function () { 
    return {
      name: this.name,
      health: this.health
    };
  },
  fromJSON: function (json) {
    var data = JSON.parse(json);
    var e = Object.create(Enemy);
    e.health = data.health;
    e.name = data.name;
    return e;
  }
}

var e = Object.create(Enemy);
e.constructor("bob");
var json = JSON.stringify(e);
var e2 = Enemy.fromJSON(json);
console.log(e.name === e2.name);

Meta-option:

A meta option would be to write the class name to the object

Game.Enemy = {
  ...
  class: "Enemy"
};

Then when you load all your json data you just do

var instance = Game[json.class].fromJSON(json);

like image 145
Raynos Avatar answered Nov 12 '22 12:11

Raynos


I think that you have to save the type on your object so that the functions can be re-added at parsing time. E.g. put a type property on your enemy in the constructor. At parsing time, first parse the string like normal JSON and then deep-traverse the resulting object. When you encounter something that was an Enemy, re-attach the methods or so.

like image 39
thejh Avatar answered Nov 12 '22 13:11

thejh