想象一下,我在JavaScript中有一个类型化的heirarchy:
function Person( newName )
{
this.name = name;
this.hats = []
}
Person.prototype = {
findHat : function( hatName ) {
var i=0;
for ( i; i< this.hats.length; i++ )
{
if ( hats[i].name === hatName )
{
return hats[i];
}
}
return { name: "no hat found" };
}
}
function Hat( name, description )
{
this.name= name;
this.description = description;
}
现在我想要做的是创建一些实例......
var bob = new Person( "Bob" );
bob.hats.push( new Hat("Top Hat", "Very smart."));
bob.hats.push( new Hat("Wooly Hat", "Very warm."));
...然后以获取简单属性并记录对象层次结构但不记录函数的方式对它们进行序列化,以便我可以将它们直接反序列化为这些类型,但是如果 - 例如 - 我想要更改findHat
的行为我可以安全地将存储的数据加载回重新定义的Person
类型。像这样:
“人:{”名称“:”bob“,”帽子“:[帽子:{”名字“:”顶帽子“,”描述“:”非常聪明。“},帽子:{”名字“: “毛茸茸的帽子”,“描述”:“非常温暖。”}]}“
显然,这是一个高度简化的模型,我正在处理现实生活中复杂且可能很深的对象层次结构,所以如果我可以避免创建任何其他类型或者在我的类上手动创建序列化和反序列化方法,那么会是理想的。
该项目完全使用在浏览器中运行的JavaScript编写,我想将数据存储在本地存储中或将其发布回服务器,所以我的假设是JSON是执行此操作的自然方式,但是我没有完全使用纯JSON序列化,它看起来好像有利于匿名类型,这使我很难将数据与对象类型相关联。有没有一种简单的方法(或标准库)可以实现这一点,还是我需要设置显式序列化所有内容为appears to have been the case a few years ago?
答案 0 :(得分:1)
JSON.parse
和JSON.stringify
都允许您插入他们正在执行的操作,因此您可以自定义序列化。此外,您可以向类型的原型对象添加toJSON
方法,调用它们将它们序列化为JSON,让您完全控制该过程。
JSON.stringify
允许您以两种方式自定义序列化结果:
如果对象采用toJSON
方法,则JSON.stringify
会使用该方法。
它允许您指定&#34;替换者&#34;为每个被序列化的项目调用的函数,以便让您有机会自定义序列化。您可以将其用作标记输出对象的机会,该输出对象具有您希望它返回时所具有的类型。
JSON.parse
可让您指定&#34; reviver&#34;功能本质上是相反的。因此,您可以在原始对象上查找特殊的序列化类型属性,并将其与原始对象数据结合使用以创建类型化对象。
我去找一个使用这些的例子,而且......呃......嗯......碰巧发现my own answer to another question进入了一些细节。 : - )
答案 1 :(得分:1)
我不喜欢JSON。*方式是,您需要编写执行序列化/反序列化的函数。我写了一个小库,可以使用它的构造函数将JSON与javascript对象混合在一起。在你的情况下像这样:
let person = JsonMix(data)
.withObject(Person, "Person")
.withObject(Hat, "Person.hats")
.build();