最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Deserialize polymorphic JSON in Javascript - Stack Overflow

programmeradmin1浏览0评论

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...

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...

Share asked Jul 6, 2014 at 11:45 RoddyRoddy 68.2k45 gold badges171 silver badges281 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

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

if you gave a better example of what the right type was, and some sample data i could provide a better answer.

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 mon 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);
    });
});   
发布评论

评论列表(0)

  1. 暂无评论