English 中文(简体)
JSON with classes?
原标题:

Is there a standardized way to store classes in JSON, and then converting them back into classes again from a string? For example, I might have an array of objects of type Questions. I d like to serialize this to JSON and send it to (for example) a JavaScript page, which would convert the JSON string back into objects. But it should then be able to convert the Questions into objects of type Question, using the constructor I already have:

function Question(id, title, description){

}

Is there a standardized way to do this? I have a few ideas on how to do it, but reinventing the wheel and so on.

Edit:

To clarify what I mean by classes: Several languages can use classes (JAVA, PHP, C#) and they will often communicate with JavaScript through JSON. On the server side, data is stored in instances of classes, but when you serialize them, this is lost. Once deserialized, you end up with an object structure that do not indicate what type of objects you have. JavaScript supports prototypal OOP, and you can create objects from constructors which will become typeof that constructor, for example Question above. The idea I had would be to have classes implement a JSONType interface, with two functions:

public interface JSONType{
  public String jsonEncode();//Returns serialized JSON string
  public static JSONType jsonDecode(String json);
}

For example, the Question class would implement JSONType, so when I serialize my array, it would call jsonEncode for each element in that array (it detects that it implements JSONType). The result would be something like this:

[{typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"},
 {typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"},
 {typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"}]

The javascript code would then see the typeof attribute, and would look for a Question function, and would then call a static function on the Question object, similar to the interface above (yes, I realize there is a XSS security hole here). The jsonDecode object would return an object of type Question, and would recursively decode the JSON values (eg, there could be a comment value which is an array of Comments).

问题回答

You ll have to create your own serializer which detects Question (and other classes) and serializes them as constructor calls instead of JSON object notation. Note that you ll need a way to map an object to a constructor call. (Which properties come from which parameters?)

Everyone else: By classes he means functions used as constructors; I assume that he s trying to preserve the prototype.

Have you looked at JSON.NET? It can serialize/de-serialize .NET objects to JS and vice-versa. It is a mature project and I highly recommend it.

Also, if you could change the definition of your Question function to take one object with properties instead of taking separate arguments, you can do something like this:

Working Demo

 function Question(args)
 {
  this.id = args.id;
  this.text = args.text;
 }

 Question.prototype.alertText = function() { alert(this.text); };

 $(document).ready(
  function()
  {
   var objectList = 
     {
       list  : [ 
       {  id  : 1,  text  :  text one  }
       ,{  id  : 2,  text  :  text two  }
       ,{  id  : 3,  text  :  text three }
       ],
       type  :  Question 
     };


   var functionName = objectList[ type ];
   var constructor = window[functionName];
   if(typeof constructor !==  function )
   {
    alert( Could not find a function named   + functionName);
    return;
   }

   var list = objectList[ list ];
   $.each(list,
    function()
    {
     var question = new constructor(this);
     question.alertText();
    }
   );
  }
 );

On a side note, please prefix your .NET Interfaces with I e.g. it should be IJsonType and not JsonType.

typeof is a keyword so specify the property name in quotes if you want to use it.

It s highly dangerous, but eval can process any text and execute it. http://www.w3schools.com/jsref/jsref_eval.asp

But DON T use it. May do something like pass over the params you want to pass into the constructor as a JSON object and call the constructor with it...

function Question({"id" : "val", "title", "mytitle", "description" : "my desc"}){
...
}

This might be useful. http://nanodeath.github.com/HydrateJS/ https://github.com/nanodeath/HydrateJS

Use hydrate.stringify to serialize the object and hydrate.parse to deserialize.

Assuming you are using a Javascript client and a REST api backend and you are looking to define the rules for encoding a Method as JSON, you should probably consider using graphQL.

You could also look at my draft Specificaton for JSON-ND - that may give you simple representation: eg

Where the server publishes this specification:

{
  "Question:POST(id:integer, title:string, description:string):string" : 
     "https://my.question.com:999/question" 
}

Or perhaps a little less "C" style

{ "QuestionParam:Interface"[
       "id:integer",
       "title:string",
       "description:string"
  ],
  "Question:POST(QuestionParam[0,]):string" : 
     "https://my.question.com:999/question" 
}

This means you can POST the following to https://my.question.com:999/question

{
  "questions:Question": [
     {id:0, title:"Some Question 1", description:"blah blah blah"},
     {id:1, title:"Some Question 2", description:"blah blah blah"},
     {id:2, title:"Some Question 3", description:"blah blah blah"}
   ]
}

And the server would respond with something like:

[
   "answer 1",
   "answer 2",
   "answer 3",
]

You might even define a better return type say "Answer"

{
  "Answer:Interface"[
    "id:integer",
    "answer:string"
  ],
  "Question:POST(id:integer, title:string, description:string):Answer" : 
     "https://my.question.com:999/question:URI" 
}

And the server would return:

{ "answers:Answer" :[
     {"id":0, "answer":"Answer 1"},
     {"id":1, "answer":"Answer 2"},
     {"id":2, "answer":"Answer 3"}
   ]
}

on the client side, implement a JSON-ND interpreter similar to the example: , include a Fetch call and you could use something like:

var questions = {
  "questions:Question": [
     {id:0, title:"Some Question 1", description:"blah blah blah"},
     {id:1, title:"Some Question 2", description:"blah blah blah"},
     {id:2, title:"Some Question 3", description:"blah blah blah"}
   ]
}
var answers = JSON_ND_Stringify(questions) ; //of course use an async call here




相关问题
Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

JSON with classes?

Is there a standardized way to store classes in JSON, and then converting them back into classes again from a string? For example, I might have an array of objects of type Questions. I d like to ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Passing another class amongst instances

I was wondering what is the best practice re. passing (another class) amongst two instances of the same class (lets call this Primary ). So, essentially in the constructor for the first, i can ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签