Or maybe even override some portion of JSON.parse to parse functions? This isn't time sensitive, I built work arounds in my code, but with the eval function, you would think that turning functions into strings and back would be a piece of cake.
Asked
Active
Viewed 903 times
0
-
What do you aim to achieve by stringify a function? – Mukund Goel Apr 15 '20 at 04:32
-
Sure, this is possible. `JSON.parse()` has a second parameter that allows manipulating the object after parsing. You need to determine how you'll identify a function vs. a regular string. – Brad Apr 15 '20 at 04:34
-
What would be a use-case for this? You only need JSON when you're transferring data from an environment to another. Then you'd need to create an interpreter on the receiving end too, functions are rarely interchangeable. Inside JS you can always use a live object containing methods. – Teemu Apr 15 '20 at 04:35
-
I have this "weapon" object, that has it's own attack function. Each weapon does it's own thing. I realized that I wouldn't ever need to save the current loadout because the characters never pickup or drop weapons. – Leif Messinger LOAF Apr 15 '20 at 05:28
2 Answers
1
It's possible, but weird, and you of course wouldn't have access to any of the outer scope of the parsed function. Call toString
to get the function's source code, trim out the brackets so you just have the function body, and have Function.prototype.toJSON
return that. Then when parsing, call new Function
on the string:
Function.prototype.toJSON = function() {
// trim out beginning and end {}s
return this.toString().match(/[^{]*(?=}$)/)[0];
};
const fn = () => {
console.log('foo');
};
const json = JSON.stringify({
str: 'str',
fn
});
console.log(json);
const parsed = JSON.parse(json);
const parsedFn = new Function(parsed.fn);
parsedFn();
But there shouldn't be a need to do this in 99% of situations. Whatever the actual issue is, there's probably a more elegant solution.

CertainPerformance
- 356,069
- 52
- 309
- 320
-
This is a potential XSS vector, don't use it with external data, including user input and your own database. – Teemu Apr 15 '20 at 05:27
0
I think no need to strip brackets. I use more simple code. It allows you to pass args to your function:
Function.prototype.toJSON = function() { return this.toString(); };
const json = JSON.stringify({
func: (a,b) => { console.log(a,b); },
a: 1
});
const parsed = JSON.parse(json);
const parsedFunc = Function('return ' + parsed.func + ';')();
parsedFunc('hello','world');

Павел П
- 109
- 3