考虑您得到了这个JSON对象:
{ id: 3, name: 'C' }
你如何判断一个对象是维生素对象还是编程语言对象?我说清楚了吗?
在强类型语言中,我们可以从对象的名称中简单地理解对象(对象的Type
)的性质。 每个对象都有一个名称。那么我们如何在JSON中实现类似的功能呢?如何为JSON对象命名?有没有已经建立的模式?
考虑您得到了这个JSON对象:
{ id: 3, name: 'C' }
你如何判断一个对象是维生素对象还是编程语言对象?我说清楚了吗?
在强类型语言中,我们可以从对象的名称中简单地理解对象(对象的Type
)的性质。 每个对象都有一个名称。那么我们如何在JSON中实现类似的功能呢?如何为JSON对象命名?有没有已经建立的模式?
{
"states": [ { id: 3, name: 'New York' } ],
"cities": [ { id: 4, name: 'New York' } ]
}
item
而不是city
和state
,你将会面临与JSON一样无法提供足够上下文的问题。 - unholysampler/states.json
,那么你应该合理地认为它是包含州信息的JSON数据类型。 - Spoike{
"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,
...
}
等等。
对于从其他地方获取的JSON,无法进行此操作。
如果您控制JSON,则可以执行以下操作:
为每个对象添加一个“类型”字段。
定制一个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()
和JSON.stringify()
一样使用这两种方法,它会起作用。但是,对于您想要支持的每种新类型,您都必须添加一个额外的case
。
不是太不安全,只是它使用了邪恶的eval()
方法。这不太好。 只要没有其他人有能力向您的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;
}
这样做的好处是不需要使用 switch-case,并且可以轻松扩展到新类型(无需进行代码更改)。
{ id: 2, name: 'something' }
,第一个对象指向一个州,第二个对象指向一个城市,第三个对象指向该城市中的一个商店,我该如何区分它们?不一定需要原型操作。 - Saeed Neamati