考虑一下你得到这个JSON对象:
{ id: 3, name: 'C' }
如何判断它是维生素对象还是编程语言对象。我明白了吗?
在类型语言中,我们只是从它的名字中理解对象的性质(对象的Type
)。 每个对象都有一个名称。我们如何使用JSON实现类似的功能?我们如何为JSON对象命名?任何已建立的模式?
答案 0 :(得分:2)
如果遇到此问题,则表示未正确定义序列化格式。您应始终能够毫无困难地从JSON对象反序列化。
有两种选择:
添加类型字段:您无法创建类型化对象,因为有多个类型具有相同的字段名称集。通过添加类型字段,对于对象的基础类型没有任何疑问。使用此选项,您将不得不在创建真实对象时完成处理类型字段的过程。
使用上下文来决定对象的类型:如果您提交的查询意味着只返回一种类型的对象,则没有问题。或者,如果可以返回多种类型,则响应格式应按类型对对象进行分组。
{
"states": [ { id: 3, name: 'New York' } ],
"cities": [ { id: 4, name: 'New York' } ]
}
答案 1 :(得分:2)
您必须添加一个描述对象类型的字段。这样你就永远不会怀疑这种类型。请查看Google's Calendar API处的示例。 Google的日历资源都有一个描述类型的字段“kind”。
Calendar Event看起来像:
{
"kind": "calendar#event",
"etag": etag,
"id": string,
"created": datetime,
"updated": datetime,
"summary": string,
...
}
A Calendar List Entry喜欢:
{
"kind": "calendar#calendarListEntry",
"etag": etag,
"id": string,
"summary": string,
"description": string,
"location": string,
...
}
等
答案 2 :(得分:1)
对于从其他地方获取的JSON,无法做到这一点。
如果你可以控制JSON,那么你可以这样做:
向每个对象添加“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;
}
现在,在“安全”方法中,我们必须为我们期望解析的每种类型创建一个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()
和JSON.stringify()
一样,它会起作用。但是对于您想要支持的每种新类型,您都必须添加额外的case
。
不是太不安全,只是因为它使用了邪恶的eval()
方法。 Which isn't too good.。只要没有其他人能够在您的JSON中添加自定义type
参数,就可以了。但是,没关系。
在这里,您使用与上面相同的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;
}
这样做的好处是不需要开关盒,并且可以轻松扩展到新类型(无需更改代码)。