3

假设您获得了这个 JSON 对象:

{ id: 3, name: 'C' }

你怎么知道它是维生素对象还是编程语言对象。我清楚了吗?

在类型化语言中,我们只是从名称中理解对象的性质(Type对象的)。每个对象都有一个名称。我们如何使用 JSON 实现类似的功能?我们如何为 JSON 对象命名?有什么既定的模式吗?

4

3 回答 3

4

如果您遇到此问题,则表示您的序列化格式未正确定义。您应该始终能够毫无问题地从 JSON 对象反序列化。

有两种选择:

添加类型字段:您无法创建类型化对象,因为有多个类型具有相同的字段名称集。通过添加类型字段,对象的底层类型毫无疑问。使用此选项,您将必须在创建真实对象时完成处理类型字段的过程。

使用上下文来决定对象是什么类型:如果您提交的查询暗示应该只返回一种类型的对象,那么就没有问题。或者,如果可以返回多种类型,则响应格式应按类型对对象进行分组。

{
  "states": [ { id: 3, name: 'New York' } ],
  "cities": [ { id: 4, name: 'New York' } ]
}
于 2012-05-30T11:10:51.587 回答
3

您必须添加一个描述对象类型的字段。这样你就永远不会怀疑类型。以Google 的 Calendar API为例。Google 的日历资源都有一个字段“kind”来描述类型。

日历事件如下所示:

{
    "kind": "calendar#event",
    "etag": etag,
    "id": string,
    "created": datetime,
    "updated": datetime,
    "summary": string,
    ...
}

日历列表条目,如:

{
    "kind": "calendar#calendarListEntry",
    "etag": etag,
    "id": string,
    "summary": string,
    "description": string,
    "location": string,
    ...
}

等等

于 2012-05-30T11:39:09.423 回答
1

对于从其他地方获取的 JSON,没有办法做到这一点。

如果您可以控制 JSON,那么您可以这样做:

  1. 为每个对象添加一个“类型”字段。

  2. 定制一个 JSON 函数来处理这个问题。这可以通过两种方式完成,一种安全,一种不安全。

安全方法

创建一个函数stringifyJSONType()。这一个像往常一样字符串化,但动态添加了一个类型参数。

 function stringifyJSONType(o){
  o.type=o.constructor.name;
  var s=JSON.stringify(o);
  delete o.type; //To be clean and not modify the object.
  return s;
 }

现在,在“安全”方法中,我们必须为我们期望解析的每种类型创建一个 switch-case。这仅允许某些类型(那些已保存在 switch-case 中的类型)。

function parseJSONType(s){
 var o=JSON.parse(s);
 switch(o.type){

  case "String":
   o.__proto__=String;
   break;
  case "Date":
   o.__proto__=Date;
   break;
  case "City": //Your custom object
   o.__proto__=City;
   break;  
  case "State": //Your custom object
   o.__proto__=State;
   break;  
  case "Country": //Your custom object
   o.__proto__=Country;
   break;  

/*.... more stuff... */


  case "Object":
  default:
   o.__proto__=Object;
   break;
  
 }
delete o.type;
return o;
}

现在,像JSON.parse()and一样使用这两种方法JSON.stringify(),它就会起作用。但是对于您想要支持的每种新类型,您都必须添加一个额外的case.

不安全的方法

不是太不安全,只是它使用了邪恶的eval()方法。这不太好。. 只要没有其他人能够type向您的 JSON 添加自定义参数,就可以了。

在这里,您使用与stringifyJSONType()上面相同的方法,但使用不同的解析方法。

 function stringifyJSONType(o){
  o.type=o.constructor.name;
  var s=JSON.stringify(o);
  delete o.type; //To be clean and not modify the object.
  return s;
 }

function parseJSONType(s){
 var o=JSON.parse(s);
 o.__proto__=eval(o.type);
 delete o.type;
 return o;
}

这样做的好处是不需要 switch-case 并且很容易扩展到新类型(不需要更改代码)。

于 2012-05-30T10:51:35.097 回答