Dmitry Kaigorodov
Dmitry Kaigorodov

Reputation: 1533

How to JSON.parse objects so that objects will be instances of the class?

I have JavaScript "Class" that makes js objects smarter. I serialize these objects to localStorage and restore them. But these restored object are not instances of a class. Restored objects are just property-sets. So, I do set __proto__ of these objects.
And I've read that using __proto__ is wrong (slow and deprecated) approach to make objects smarter.

What is smart solution for these problem? How to restore JavaScript objects so that they will be instances of the corresponding classes?

var showMarks = function (locals) {
    var myMarks = locals.myMarks = locals.myMarks.slice(0, 120);
    for (var i = myMarks.length - 1; i >= 0; i--) {
        myMarks[i].__proto__ = Mark.prototype;
    }
}

showMarks(JSON.parse(localStorage.myMarks));

Upvotes: 1

Views: 320

Answers (3)

axelduch
axelduch

Reputation: 10849

UPDATE According to comment, I added a replacement of original literal objects foreach myMarks

You could first instanciate your class, then loop through your object's properties to set them after instanciation

var mark, key;
for (var i = myMarks.length - 1; i >= 0; i--) {
    mark = new Mark();
    for (key in myMarks[i]) {
        if (myMarks[i].hasOwnProperty(key)) {
            mark[key] = myMarks[i][key];
        }
    }
    // replace previous plain object with the new instance of Mark
    myMarks[i] = mark;
}

Upvotes: 2

Tibos
Tibos

Reputation: 27823

The correct solution is to have a method to serialize and one to unserialize your instance. JSON.stringify/parse work well for plain objects, but if you want more, you have to make your custom methods.

Example with class that has private properties:

function Cls(name) {
  var private_name = name; // private!
  this.getName = function() { return private_name; }
}

Cls.prototype.sayHi = function() {
  console.log(this.getName() + ' says hi!');
}

// serialization
Cls.prototype.toJSON = function() {
  return JSON.stringify({ // add what you need to reconstruct the class in it's current state
    name : this.getName()
  });
}

Cls.fromJSON = function(str) {
  return new Cls(JSON.parse(str).name); // you might need to have a special case in the constructor for this
}

// usage:
var c = new Cls('me');
var serialization = c.toJSON();
var clone = Cls.fromJSON(serialization);
clone.sayHi()

Upvotes: 1

S1cK94
S1cK94

Reputation: 43

I suppose you can add a property indicating the class they belongs to before storing them (ie: .__class).
Then, you can write a function (let's say restore(obj)):

function restore(obj){
    switch(obj.__class){
        case "Class1":
            return new Class1(obj.a, obj.b);
    }
    return null;
}

Upvotes: 1

Related Questions