9

I see how I can write objects to files as described here: How can I save objects to files in Node.js? but is there a way to take an object and write it in a way that allows me to reload the object into memory including its methods?

3
  • 2
    Writing and reading functions presents a huge risk for injection. I would consider the security implications of this decision. Commented Jun 30, 2012 at 16:40
  • I agree with Anthony. If you really need it, though, you can simply save the JavaScript code, then load it and call eval on it. Commented Jun 30, 2012 at 16:57
  • I agree on the security concerns. I'm just playing around with an idea. Thanks! Commented Jun 30, 2012 at 20:08

3 Answers 3

6

As @AnthonySottile said before, this can be extremely dangerous and I'm not sure there is ever a good use case for it, but just for kicks and giggles you would need to write your own recursive serializer. Something like this:

var toString = Object.prototype.toString;

function dump_object(obj) {
    var buff, prop;
    buff = [];
    for (prop in obj) {
        buff.push(dump_to_string(prop) + ': ' + dump_to_string(obj[prop]))
    }
    return '{' + buff.join(', ') + '}';
}

function dump_array(arr) {
    var buff, i, len;
    buff = [];
    for (i=0, len=arr.length; i<len; i++) {
        buff.push(dump_to_string(arr[i]));
    }
    return '[' + buff.join(', ') + ']';
}

function dump_to_string(obj) {
    if (toString.call(obj) == '[object Function]') {
        return obj.toString();
    } else if (toString.call(obj) == '[object Array]') {
        return dump_array(obj);
    } else if (toString.call(obj) == '[object String]') {
        return '"' + obj.replace('"', '\\"') + '"';
    } else if (obj === Object(obj)) {
        return dump_object(obj);
    }
    return obj.toString();
}

This will handle most types, but there is always the chance of an oddball messing it up so I would not use this in production. Afterwards unserializing is as easy as:

eval('var test = ' + dump_to_string(obj))
Sign up to request clarification or add additional context in comments.

5 Comments

O_O Why are you re-inventing the wheel? Define the toJSON method for custom serialization of an object, eg. <SomeObject>.prototype.toJSON. For even more flexibility, define a replacer for JSON.stringify.
@RobW Did not know about either of those. Very useful, Thanks!
dump_to_string the replace function for "'s has to be global, eg: obj.replace(/\"/g, '\\"') Supplied an edit but I think it got maybe rejected, dunno :)
Agree with @jaywink, obj.replace should be using /"/g to ensure all " get replaced correctly, not just the first one.
It's been 4 years since this answer was given, but it just saved me! You made my day! Thank you so much!!!
2

The question is quite old, but I couldn't find anywhere some simple solution to the question of effective serialization in JavaScript.
One could use BSON (MongoDB inner objects representation) which uses a binary format to represent objects in memory.

I could not find some link to the documentation, but the code is well documented and I came up with something like this :

fs = require 'fs'
bson = require('bson').BSONPure.BSON

obj = {
  string: "test",
  func: (s) ->
    console.log s
}

fs.writeFile 'test.txt', bson.serialize(obj, false, false, true), (err) ->
  return console.log("Err : #{err}") if err
  fs.readFile 'test.txt', (err, file) ->
    return console.log("Err : #{err}") if err
    deserialized = bson.deserialize file, evalFunctions: true
    deserialized.func deserialized.string // Outputs 'text', as expected

It is coffee-script but the code is simple enough for everyone to understand.

1 Comment

Careful with that 'evalFunctions: true' option since it will allow javascript execution (see gist.github.com/DinisCruz/245716893d783ea740ea)
0

I recently wrote shoveJS: https://shovemedia.github.io/shovejs/ to handle exactly this sort of thing. YMMV -- I haven't tried it with Node yet.

It converts a typed object structure to JSON (which you'd then save to disk) and can inflate that structure back into typed objects including proper object -> object references etc. To be clear, the method / class definitions themselves are NOT serialized. The system simply expects that registered Model / Factory classes available during serialization are also available during deserialization.

Apologies in advance for not having some simple examples posted.

edit: the technique is a souped-up take on what Rob W mentions in his comment below

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.