类似Python的对象序列化,用于完整的Javascript对象

27

有没有适用于Javascript的序列化框架,可以像Python pickles一样保留类和引用信息?也就是说,可以直接将原型继承的类实例(不仅仅是类似JSON的数据)序列化,例如:

 // Somehow add serialization metadata to classes first
 obj = new MyObject();
 obj.referred = new MyObject2();
 pickle = serializer.dump(obj) // Provides byte stream of the serialized object  

序列化程序可以处理以下事项:

  • 将类信息编码到pickle中-由于存在不同的JS类系统,这应该是可定制的

  • 自动跟随并序列化引用的对象

  • 提供钩子以添加自定义编码器/解码器以处理值(日期是最常见的情况)

这将使内部存储和传输复杂数据结构变得更加容易。我希望在游戏引擎中使用它。与pickle一样,如果原始Javascript代码未提供类定义,则无法对数据进行反序列化。

已经存在哪些此类Javascript框架,还是我需要推出一个自定义系统?


你最终使用了什么?我正在寻找类似的解决方案... - Nick Dima
occamsrazor.js(见第一个答案)在我看来是最好的,尽管只是半自动化的。 - Mikko Ohtamaa
6个回答

4
您可能想看看hunterloftis/cryo。从自述文件中可以看到:

适用于node.js和浏览器。Cryo受Python的pickle启发,类似于JSON.stringify()和JSON.parse()。 Cryo.stringify()和Cryo.parse()在以下情况下改进了JSON:

  • 未定义
  • 日期
  • 无穷大
  • 对象引用
  • 附加属性
  • 函数
  • DOM节点

作者在r/programming上进行了简短的讨论。

源代码很简单,没有魔法。

我还没有尝试过它。


4

虽然不是完美的解决方案,但您可以尝试使用occamsrazor.js。通过这样做,您可以使用JSON序列化:

// this is your costructor function
function Circle(attrs){
    this.radius = attrs.radius;
}
Circle.prototype.area = function (){
    return this.radius*this.radius*Math.PI;
}
Circle.prototype.perimeter = function (){
    return 2*this.radius*Math.PI;
}

// this is a validator
function hasRadius(obj){
    return radius in obj;
}

// this is your factory function
objFactory = occamsrazor().addContructor(hasRadius, Circle);

// this is your deserialized object
var json = '{"radius": 10}';

// circle now is a full fledged object
var circle = objFactory(JSON.parse(json));

缺点是你不像使用pickle一样获得对象的快照,而是重新创建一个新对象。但在某些情况下可能很方便。

谢谢。如果需要实现这样的系统,最好建立在occamrazor.js的基础之上 :) - Mikko Ohtamaa

2

虽然不完全是我想要的,但至少有一个很好的代码库可以开始工作,对对象图进行平面化等操作 :) - Mikko Ohtamaa

1

js-yaml可以使用dump(即dangerousDump)和load(即dangerousLoad)方法。我认为大多数编程语言都实现了YAML。

否则,您需要提供如何序列化/反序列化JSON.stringify(replacer)和JSON.parse(reviver)的方法。

我基于https://github.com/patarapolw/any-serialize创建了一个库,并测试了Date、RegExp、Set、Function、Class constructor、Infinity、NaN、BigInt、Symbol、Undefined等类型。

对于自定义的Class实例,您需要提供相应的方法。


1

以下是一些推荐:

Jason:完全透明化披露:这个我制作了。但我使用它,它是我完整的JavaScript序列化的首选推荐。您使用此库可能会遇到比其他库更少的问题,如果它不符合您的需求,我很高兴为其添加功能!支持原型/构造函数信息,同一对象的多个引用,有用户定义类型的钩子。除非您将原型显式添加到“常量”列表中,否则会保存原型的副本,在重建时使用已存在的原型。具有JSON样式的替换器和引用在解析时将存在的对象的方法。可以序列化Date、RegExp、null、NaN、Infinity、-Infinity、function、DOM元素、事件和普通对象。尚未经过严格测试,但如果它无法正常工作,您可以给我发电子邮件,我会尝试修复。https://github.com/johnlarson/Jason

ResurrectJS: 原型/构造函数信息,同一对象的多个引用,无钩子。使用 'constructor' 属性来获取构造函数,并且在构造函数的命名空间方面有一定限制,可以通过自定义命名空间解析器绕过这些限制。具有 JSON 风格的替换器。序列化 Date、RegExp、DOM 元素、NaN、Infinity、-Infinity 和普通对象。比 Jason 更成熟,经过更多的使用测试,但使用起来更难正确使用。https://github.com/skeeto/resurrect-js SnapShot: 我没有尝试过这个库。它看起来很有前途,但是最后更新于 3 年前。据我所知,没有自动原型/构造函数信息,但它具有类似于 JSON 的 toJSON 和 fromJSON 的自定义序列化/反序列化行为的钩子 API。处理同一对象的多个引用。据我所知,没有 JSON 风格的替换器。序列化 Date、RegExp、null 和 function。https://github.com/mixu/snapshot JASON: 这是另一个有前途的库,我没有试过,最后更新于3年前。我不知道它是否支持原型/构造函数。处理对同一对象的多个引用。据我所知,它没有钩子。我不知道它是否有JSON风格的替换程序。序列化'Dates, RegExps, Booleans, etc.'和'所有JS原语,包括undefined'。https://github.com/xk/JASON

1

看看msgpack。虽然我没有在JavaScript对象中使用过它,但示例似乎意味着它可以用于对象而不仅仅是JSON。额外的好处是:它是我用过的序列化实现中最快的之一。


我检查了msgpack,但是没有找到完整的JavaScript对象的示例 :( - Mikko Ohtamaa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接