Javascript 将自定义对象转换为JSON,然后再返回自定义对象?
我见过与此非常相似的问题,但我不能确定这些问题是否得到了明确的回答——也许我有点糊涂,对不起 我想拥有自己对象的便利性(和清晰性),称之为Javascript 将自定义对象转换为JSON,然后再返回自定义对象?,javascript,json,object,Javascript,Json,Object,我见过与此非常相似的问题,但我不能确定这些问题是否得到了明确的回答——也许我有点糊涂,对不起 我想拥有自己对象的便利性(和清晰性),称之为CardboardBox()。它不包含代码,只包含数据。我想将其写入数据库,稍后再将其读回,但显然,读回时它是一个类型Object()。我所能想到的是要找出它曾经是什么: 有一个成员变量type,我将其设置为carboard\u BOX 实例化一个新的CarbardBox()并使用一个函数(在框中)将Object()的属性复制到新的CardboardBox()
CardboardBox()
。它不包含代码,只包含数据。我想将其写入数据库,稍后再将其读回,但显然,读回时它是一个类型Object()
。我所能想到的是要找出它曾经是什么:
type
,我将其设置为carboard\u BOXCarbardBox()
并使用一个函数(在框中)将Object()的属性复制到新的CardboardBox()
对象
function CardboardBox(n) {
this.name = n;
}
var box = new CardboardBox("My Box");
send = JSON.stringify(box); // JSON CarboardBox()
obj = JSON.parse(send, function fn(obj) { // Object() returned
log("OB: "+obj.type);
return obj.type === 'CardboardBox' ? new CardboardBox(obj) : CardboardBox;
});
console.log(obj);
输出为:
OB: undefined utils.js:40
OB: undefined utils.js:40
function CardboardBox(n) {
this.name = n;
}
一种可能的解决方案如下:
function CardboardBox(n) {
if(typeof(n) == 'string') {
//build from name string
this.name = n;
} else {
//build from object
this.name = n.name;
}
//add in this object's "type" in a place
//that is unlikely to exist in other JSON strings
this.__type = 'CardboardBox';
}
var box = new CardboardBox("My Box");
send = JSON.stringify(box), // JSON CarboardBox()
obj = JSON.parse(send, function(key, val) {
//if this is an object, and is CardboardBox
if(typeof(val) === 'object' && val.__type === 'CardboardBox')
return new CardboardBox(val);
return val;
//or if your object is in a context (like window), and there are many of
//them that could be in there, you can do:
//
//if(typeof(val) === 'object' && context[val.__type])
// return new context[val.__type](val);
});
console.log(obj);
基本上,将对象类型存储在稍后解析json时要查找的位置。如果有多个对象可以在单个范围内实例化,那么第二种解析方法可能更合适。这也将解释JSON中不是CarboardBox
s的对象
编辑下面是这个方法的一个例子。总的来说,你是正确的:Javascript没有任何内置的方式来序列化普通对象以外的任何东西,因此在反序列化JSON时,从JSON转到JSON不会生成特定的类。因此,您需要自己进行序列化/反序列化,或者使用提供一些支持的库 我个人喜欢这个问题,因为它可以很好地处理序列化和反序列化。您定义了一个模型类,其中包括一个将其数据以序列化形式保存到服务器的方法,以及一个将其反序列化回模型的方法。这里的关键设计问题是,反序列化是在知道要反序列化到的模型的情况下执行的:
- 您可以调用
根据模型id从服务器获取数据,或者myModel.fetch()
- 将一组新数据传递给模型构造函数:
,或newmodel(serializedData)
- 将多个模型的数据数组传递给知道模型类型的集合:
newmodelcollection(arrayOfSerializedData)
var classes = {
CardboardBox: ...,
AluminumBox: ...
}
function Deserializer(json) {
// parse if you're actually dealing with a string
var data = JSON.parse(json),
// now look for some custom type flag - you'll need to set this yourself
type = data.type,
// class lookup, perhaps with a default
Cls = classes[type] || DefaultType;
return new Cls(data);
}
var obj = new Deserializer(send);
obj instanceof CardboardBox; // should work
尽管如此,这仍然依赖于一个自定义标志来切换类型——我不确定是否有办法解决这个问题。看看JSON.parse和JSON.stringify参数。可以对每个对象进行自定义回调
JSON.parse(obj,fn);函数fn(obj){return obj.type=='a'?新的a(obj):a;}
如果我有时间的话,我会写一个正确的答案。对不起,谢谢你的回复。非常感谢,但我现在有点困惑了。如果我在我的CardboardBox()
上使用函数(fn),那么从JSON.parse()
返回的是CarboardBox()
的构造函数<代码>对象类型始终未定义。我想我遗漏了什么…@Steve:你必须设置。键入
,而且你没有正确使用参数(第一个参数不是建议的obj
)。请参阅。为什么测试代码不设置类型
成员?这就是为什么type
是未定义的。是的,这几乎就是我的解决方案。我只是想知道有没有更好的办法。希望JavaScript有合适的类。我想我将以某种JavaBean类型的东西作为结束。不是JavaScript“没有合适的类”,而是JSON格式不支持自定义对象。不幸的是,你必须解决这个问题,据我所知,这(或一个变体)是实现它的唯一途径。即使它是使用主干或一些框架抽象出来的,它也只是在幕后做一些类似的事情。所有这些都是非常好的答案。谢谢我可能最终会编写自己的JSON包装器。如果在反序列化之后无法将对象放入正确的类中,代码将变得混乱,并且/或者我将在以后对对象进行额外的工作。
var classes = {
CardboardBox: ...,
AluminumBox: ...
}
function Deserializer(json) {
// parse if you're actually dealing with a string
var data = JSON.parse(json),
// now look for some custom type flag - you'll need to set this yourself
type = data.type,
// class lookup, perhaps with a default
Cls = classes[type] || DefaultType;
return new Cls(data);
}
var obj = new Deserializer(send);
obj instanceof CardboardBox; // should work