Deserialize polymorphic JSON in Javascript

My client code receives a JSON object from the server and then parses it. The parsed element contains a type property that should control the class of the object.

$.getJSON("foo.json").done(function(data, textStatus, xhr) {
    $.each(data.objects, function(key, val)
    {
      if (val.type = "A") // make val into an object of class A, somehow?
        ...
      else if (val.type = "B") // make val into an object of class B somehow?
        ... etc...
    }
}    

How can I create a JavaScript object of the correct type without explicitly copying each property or, alternatively, converting the parsed object to another type?

I read a little about __proto__, but I feel that this is a big sledgehammer, for which there should be a small nut ...

I saw similar questions regarding Java and Jackson, but nothing for Javascript ...

+4
source share
2 answers

you could do something like this

function ObjectFactory() {
    this.newInstance = function(val) {
      if (val.type == "A") return new A(val);
      if (val.type == "B") return new B(val);
    }
}    
function A(data) {
    // do something with the data
    this.property = data.property;
}

function B(data) {
    // do something with the data
    this.property = data.property;
    this.bSpecificProperty = data.bSpecificProperty;
}

$.getJSON("foo.json").done(function(data, textStatus, xhr) {
    var objectFactory = new ObjectFactory();
    var objects = $.map(data.objects, objectFactory.newInstance);

    console.log(objects);
}   

, , .

+4

, - - , , , , - . , ... JSON $.extend ?

"" - , . :

function namespace(str, scope){
    scope = scope || window;
    var parts = str.split('.');
    while(parts.length) 
        scope = scope[parts.shift()];
    return scope;
}

Foo = {};
Foo.Bar = function(conf){
    // some kind of constructor
    $.extend(this, conf);
};
// test...
var json = {
    type: 'Foo.Bar',
    var1: 1,
    var2: 2,
    var3: 3
};

var obj = new (namespace(json.type))(json);
console.log(obj, obj instanceof Foo.Bar);

... :

$.getJSON("foo.json").done(function(data, textStatus, xhr){
    data.objects = $.map(data.objects, function(obj){
        return new (namespace(obj.type))(obj);
    });
});   
+2

Source: https://habr.com/ru/post/1547309/


All Articles