Deserialize polymorphic JSON in Javascript

javascript, json, polymorphism

Solution

You haven't specified what - if any - pattern you are implementing but as another answer has alluded to, you will have to adopt some kind of convention during an object's construction. You don't necessarily have to explicitly account for each type though... and you could also be a little lazy merging your JSON data with `$.extend` if you are satisfied with it's integrity?

I'd also include a helper function for resolving "types" within a given scope - it's a common practice to namespace objects in a project to avoid polluting the global scope. For example:

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);

fiddle ... or to fit with your own code:

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

Problem

My client-side code gets a JSON 'object' from the server, and then parses it. The parsed object contains a 'type' property, which 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 over each property , or - alternatively - convert the parsed object to a different type? I've read a little about `__proto__` but get the feeling that it's a big sledgehammer for what should be a small nut... I've seen similar questions regarding Java and Jackson, but nothing for Javascript...

Original source