jonemo
jonemo

Reputation: 372

Inverse operation for Javascript's Function.toString()

For Javascript application I need to be able to let the user save the state of an object. This involves saving a set of custom functions that were previously created dynamically or through a GUI, and loading these stored functions later. Essentially I need to serialize and unserialize functions.

Right now I achieve the serialize part by using the Function object's .toString() method:

func.toString().replace('"', '\"').replace(/(\r)/g, ' ').replace(/(\n)/g, ' ').replace(/(\t)/g, ' ')

This gives me "serialized" functions like this beauty (note that the function is unnamed):

"function (someParameter) {this.someFunctionName(return 'something';}"

Unserializing this is where I struggle. My current best solution for unserializing the functions is this:

var func = eval( 't =' +  so.actions[i].func);

Note how I prepend the serialized function with t = before calling eval() on it. I don't like doing this because it creates a global variable but I cannot find a way around it. When not prepending this, I receive a "SyntaxError: Unexpected token (". When prepending var t =, eval() does not return the function but undefined.

Are there alternative ways to "unserialize" an unnamed function?

PS: I am aware of the security implications of using eval() on user input. For the foreseeable future I am the only user of this software, so this is currently a non-issue.

Upvotes: 6

Views: 3427

Answers (2)

user123444555621
user123444555621

Reputation: 152966

This should work:

eval('var func = ' + so.actions[i].func);

Upvotes: 0

Conrad Irwin
Conrad Irwin

Reputation: 1312

You could use the Function constructor to avoid creating a global variable:

var func = Function("return " + so.actions[i].func)();

This is equivalent to:

var func = eval("(function () { return " + so.actions[i].func + " })()");

One thing to be wary of is the surrounding closure which you won't be able to capture, so variables inside the function will "change" when you serialize and de-serialize.

edit

I'm not thinking, you can of course just do:

var func = eval("(" + so.actions[i].func + ")");

Upvotes: 7

Related Questions