views:

91

answers:

2

I need to serialize and deserialize Javascript objects to store them in a DB.

Note that these objects contain functions, so I can't store them as JSON, so I can't use json2.js.

What's the state of the art in [de]serialization of javascript objects (in javascript of course).

Thanks, Stewart

+3  A: 

use gserializer:

http://www.onegeek.com.au/articles/programming/javascript-serialization.php

the code in google :

http://code.google.com/p/gserializer/

GSerializer is a javascript library to serialize/deserialize javascript objects to and from strings, for persistance in say, a Cookie. Unlike many other implementations, GSerializer can also serialize functions and non-JSON notation.

Haim Evgi
I came across that earlier but I wasn't sure about the project's maturity. Have you used it personally?
Stewart Johnson
no i dont use it, sorry
Haim Evgi
Looks like it won't work: Gserializer TODO says: "Implement passing parameters into serialized functions (currently only supports no-argument functions)", and the objects I've got to serialize contain functions with arguments (toUrlValue function on LatLng object: http://code.google.com/apis/maps/documentation/javascript/reference.html#LatLng). Thanks anyway!
Stewart Johnson
sorry 2, i hope they finish this project
Haim Evgi
+1  A: 

In general, there's no way (in a browser) so serialize objects with functions attached to them, since every function has a reference to it's outer scope. If the function references any of those variables, they won't exist anymore when you deserialize it.

What I would to is use the built-in (or json2.js) JSON.stringify and JSON.parse functions with the replacer and reviver parameters. Here's a partial example of how it would work:

JSON.stringify(yourObject, function(name, value) {
    if (value instanceof LatLng) { // Could also check the name if you want
        return 'LatLng(' + value.lat() + ',' + value.lng() + ')';
    }
    else if (...) {
        // Some other type that needs custom serialization
    }
    else {
        return value;
    }
});

JSON.parse(jsonString, function(name, value) {
    if (/^LatLng\(/.test(value)) { // Checking the name would be safer
        var match = /LatLng\(([^,]+),([^,]+)\)/.exec(value);
        return new LatLng(match[1], match[2]);
    }
    else if (...) {
        ...
    }
    else {
        return value;
    }
});

You can use any serialization format you want in your custom types. The "LatLng(latitude,longitude)" format is just one way of doing it. You could even return a javascript object that can be serialized to JSON natively.

Matthew Crumley
Interesting. I read the json2.js docs ("Values that do not have a representation in JSON (such as functions and undefined) are excluded.") and assumed that the replacer/reviver functions aren't called on functions. Is this code you've actually written and used?
Stewart Johnson
@Stewart: The idea is that you avoid having to serialize the functions by re-constructing the objects when you deserialize them. The `LatLng` constructor will add the functions back in for you.The replacer will work on functions though, so if you really want to, you could try converting the function to a string. Just be aware that it won't work in every case.
Matthew Crumley