30

Why doesn't this produce anything?

console.log(JSON.stringify(function(){console.log('foobar');}));
wwaawaw
  • 6,867
  • 9
  • 32
  • 42
  • http://stackoverflow.com/questions/3685703/javascript-stringify-object-including-members-of-type-function – danp Sep 29 '12 at 10:49

7 Answers7

46

JSON can't stringify functions at all, it handles them just like undefined or null values. You can check the exact algorithm at EcmaScript 5.1 §15.12.3, see also the description at MDN.

However you of course can stringify function expression by casting them to a string, try

console.log("" + function(){console.log('foobar');})
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Hi Bergi, I passed my casted function to my web worker, however how do I reconvert back to js? JSON.parse? – Ted Fitzpatrick Jun 23 '17 at 23:30
  • @TedFitzpatrick `eval`. Of course it only works for functions without free variables. – Bergi Jun 24 '17 at 17:30
  • Thanks Bergi. I'm passing a constructor function expression that itself has internal function statements. When I eval() I'm getting "unexpected token (". I tried removing the surrounding "function(){}" block however still getting the error ... can eval'd strings contain functions? – Ted Fitzpatrick Jun 26 '17 at 16:53
  • Answered my own question. Yes the function expression can contain function statements. And, before eval I needed to add surrounding parentheses so that the parser evals the expression as an expression. – Ted Fitzpatrick Jun 26 '17 at 17:48
  • Are you able to go back to a function from the string? – Big Money Dec 06 '18 at 00:03
  • 1
    @BigMoney To *a* function, maybe, but it will be a completely new instance. And if the function was a closure, you won't know the values of the free variables. – Bergi Dec 06 '18 at 09:26
12

yourFunctionName.toString(); will also stringify a function

auraz
  • 121
  • 1
  • 3
8

JSON has no means to represent a function. It is a data format designed for simplicity and compatibility across languages (and a function is the last thing that will be cross-language compatible).

From the docs for JSON.stringify:

If undefined, a function, or an XML value is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
6

If you want to use JSON.stringify to also convert functions and native objects you can pass a converter function as the second argument:

const data = {
  fn: function(){}
}

function converter(key, val) {
  if (typeof val === 'function' || val && val.constructor === RegExp) {
    return String(val)
  }
  return val
}

console.log(JSON.stringify(data, converter, 2))

Return undefined from the converter function if you want to omit the result.

The third parameter is how many spaces you want the output to indent (optional).

Vidar
  • 1,008
  • 14
  • 16
3

You cannot do that, but there are some third party libraries can help you do that, like: https://www.npmjs.com/package/json-fn

Xin
  • 33,823
  • 14
  • 84
  • 85
1

There are couple of ways to do this.

Let's say you have function foo

> function (foo) { return foo}

if you console log it it returns function name with type

> console.log(foo)
[Function: foo]

when it comes to get access to stringified version of it, you can use one of the ways listed below.

> console.log(`${foo}`)
function (bar) { return bar}
undefined
> console.log(foo.toString())
function (bar) { return bar}
undefined
> console.log("" + foo)
function (bar) { return bar}
undefined
Tahsin Turkoz
  • 4,356
  • 1
  • 27
  • 18
1

Well there are two ways I know of doing this, first is just String(function) and you can just do eval() on what that returns. There's also a way to run the code in the function directly with regex, it would look something like this:

String(function).replace(/\w+\s{1}\w+\(\)\s?\{(\n\s+)?|\(\)\s?=>\s?{(\n\s+)?/, '').replace(/\n?\}/, '')

with the regex example when you do eval() it runs the code from the function. For both examples where it says "function" put in the name of your function with no () at the end.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49