我已经看到了非常相似的问题,但我无法确定他们是否得到了明确的回答 - 也许我有点密集,对不起。
我想拥有自己对象的方便性(和清晰度),称之为CardboardBox()
。它不包含代码,只包含数据。我想将它写入数据库并稍后再读回来,但很明显,当它被回读时它是一个类型Object()
。我能想到的只是找出它曾经是:
type
CarbardBox()
并使用函数(在框中)将Object()
的属性复制到新的CardboardBox()
对象有更好的方法吗?我很确定我可以更改实际类型。
function CardboardBox() {
this.type = "CARDBOARD_BOX"
this.name = "No set";
this.populate = new function(obj) {
// populate this object with obj properties
}
var box = new CarboardBox(); // CarboardBox
box.name = "My Box";
send = JSON.stringyfy(box);
.
.
.
obj = JSON.parse(send); // Object
if (obj.type == "CARDBOARD_BOX") {
savedBox = new CardboardBox();
savedBox.populate(obj);
}
提前致谢... 史蒂夫
[edit]我的测试代码。
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;
}
答案 0 :(得分:5)
一种可能的解决方案如下:
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
的对象。
修改以下是此方法的jsFiddle。
答案 1 :(得分:1)
总的来说,你是对的:Javascript没有任何内置的方法来序列化除普通对象之外的任何东西,因此当你反序列化时,往返JSON不会产生特定的类。因此,您需要自己完成序列化/反序列化,或者使用提供一些支持的库。
我个人喜欢Backbone.js这个问题,因为它很好地处理序列化和反序列化。您可以定义一个模型类,其中包括一个以序列化形式将其数据保存到服务器的方法,以及一种将其反序列化回模型的方法。这里的关键设计问题是执行反序列化知道您要反序列化的模型:
myModel.fetch()
根据型号ID或new Model(serializedData)
或new ModelCollection(arrayOfSerializedData)
。Backbone不做的是处理未知类型的类型转换数据。当我处理这个问题时,我通常会做一些类似@ Chad的回复,但是使用中间人;您可以将其视为代理模型或工厂:
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
但仍然依赖于自定义标志来切换类型 - 我不确定是否有任何解决方法。