Search code examples
javascriptserializationjavascript-objectsstringify

Dump JavaScript object including function bodies as "good enough" formattable code


There are lots of old questions about dumping JavaScript objects.

But of the ones which specify dumping the contents of functions, I can only find ones that emit those functions as strings in quotes (with internal quotes escaped).

What I want is something that dumps objects, including functions, in full, in a plain old JavaScript format ready to be pretty printed.

  • I do not need full serialization and deserialization like some previous questions.
  • I do need to see the object as text. Just using console.log() requires interaction to unfold object members etc. Saving the console buffer as text after console.log() does not result in plain js syntax that can be pretty printed.
  • Emit placeholders or such for references that can't be dumped (circular refs, DOM refs, etc). Shouldn't just barf when it hits one.

Here's the naive approach that dumps function text but as quoted strings that a pretty printer will not format as code:

JSON.stringify(someObject, function(key, val) {
  return (typeof val === 'function') ? val.toString() : val;
}, 4);

For the test object {a: 1, b: 'bb', c: "bb", f: function e() {return "x";} } the naive approach outputs:

{
    "a": 1,
    "b": "bb",
    "c": "bb",
    "f": "function e() {return \"x\";}"
}

What I need is:

{
    "a": 1,
    "b": "bb",
    "c": "bb",
    "f": function e() {
        return "x";
    }
}

I'm happy for this to be closed as a duplicate if one of the previous answers does what I want. I looked at many of them and can't find it.

(Use case: Making a TaperMonkey userscript for a third party site. I need to see what is actually exposed to find places to add userscript hooks. I will beautify the output, print it out, load it into a code editor, etc)


Solution

  • Don't use JSON.stringifiy - JSON cannot represent functions, and therefore you will never get it into returning what you want.

    Since you are targeting only a specific browser, maybe you can use uneval or .toSource. If you're not using Firefox, have a look at this polyfill.