简体   繁体   中英

Python-like pickling of full Javascript objects

Is there any serialization framework for Javascript which would retain class and reference information like Python pickles? Ie one could directly take a prototypial inherited class instance (not just JSON-like data) and serialize it like::

 // 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  

The serializer could take care of

  • Encoding class information in the pickle - this should be somehow customizable due to different JS class systems in existence

  • Automatically follow and serialize referred objects

  • Provide hooks to add custom encoders/decoders for values (dates being the most common case)

This would making internal storing and transferring of complex data structures little bit easier. I am hoping to use this in a game engine. Like with pickles, the deserialization of data would not be possible without the orignal Javascript code providing the class definitions.

What kind of such frameworks exist for Javascript already exist or I am going to need to roll-out a custom system?

It doesn't fit perfectly but you can try to use occamsrazor.js . Doing this you can use JSON serialization:

// 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));

The drawback is that you don't get a snapshot of an object like using pickle, you recreate a new object. But it may be convenient in some circunstances.

You might want to look at hunterloftis/cryo . From the readme:

Built for node.js and browsers. Cryo is inspired by Python's pickle and works similarly to JSON.stringify() and JSON.parse(). Cryo.stringify() and Cryo.parse() improve on JSON in these circumstances:

  • Undefined
  • Date
  • Infinity
  • Object references
  • Attached properties
  • Functions
  • DOM Nodes

There is a brief discussion with the author at r/programming .

The source is straightforward, no magic.

I haven't tried it yet.

Check out msgpack . While I have not used it for JavaScript objects, the example seems to imply that it will work for objects and not just JSONs. An added bonus: it's one of the fastest implementations that I've ever used for serialization.

Here's a few:

Jason: Full disclosure: I made this one. But I use it, and it is my top recommendations for complete javascript serialization. You'll probably experience a lot less pain using this one than any of the other ones, and I would be ecstatic to make additions to the library if it doesn't fit your needs! Prototype/constructor information, multiple references to the same object, has hooks for user-defined types. Saves copy of prototype unless you explicitly add the prototype to the 'constants' list, in which case it uses the already-existing prototype when rebuilding. Has JSON-style replacer and ways of referencing objects that will exist at the time of parsing. Serializes Date, RegExp, null, NaN, Infinity, -Infinity, function, DOM Element, Event, and normal objects. Still not a tried and tested library, but if it doesn't work for you, you can email me and I'll try to fix it. https://github.com/johnlarson/Jason

ResurrectJS: Prototype/constructor information, multiple references to the same object, no hooks. Uses 'constructor' property to get constructor, and there are certain restrictions with namespaces of constructors, which you can get around with a custom namespace resolver. Has JSON-style replacer. Serializes Date, RegExp, DOM Elements, NaN, Infinity, -Infinity, and normal objects. More mature and more tested by usage than Jason, but harder to use correctly. https://github.com/skeeto/resurrect-js

SnapShot: I haven't tried this one. It looks promising, but was last updated 3 years ago. No automatic prototype/constructor information, as far as I can tell, but it has a hook api for defining custom serialization/deserialization behavior similar to JSON's toJSON and fromJSON. Handles multiple references to the same object. No JSON-style replacer, as far as I can tell. Serializes Date, RegExp, null, and function. https://github.com/mixu/snapshot

JASON: Another promising library I haven't tried that was last updated 3 years ago. I don't know whether it does prototype/constructors. Handles multiple reference to same object. As far as I know, it doesn't have hooks. I don't know whether it has a JSON-style replacer. Serializes 'Dates, RegExps, Booleans, etc.' and 'all JS primitives, including undefined'. https://github.com/xk/JASON

js-yaml with dump (ie dangerousDump) and load (ie dangerousLoad). I think YAML is implemented in most languages.

Otherwise, you have to provide how-to serialize / deserialize for JSON.stringify (replacer) and JSON.parse (reviver).

I made a library based that that https://github.com/patarapolw/any-serialize , and tested for Date, RegExp, Set, Function, Class constructor, Infinity, NaN, BigInt, Symbol, Undefined.

For custom Class instances, you will have to provide how-to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM