7

If I put a function into a string like this:

var functionString = function (message) {
    console.log(message);
}.toString();

Is there any way to convert the string back to a function and call it? I tried

eval(functionString)

which returns "Uncaught SyntaxError: Unexpected token", and

functionString.call(this, "HI!");

which returns 'undefined is not a function'.

Is that even possible in javascript?

Thanks in advance for any reply!

EDIT: The point of this question is that the function has been converted into a string using toString(). So

console.log(functionString);

returns this string: "function (message) {console.log(message);}"

Can I transform the string back into a function and call it? That's the problem I am trying to solve. Thanks!

user1840267
  • 408
  • 1
  • 5
  • 18
  • It would help if you'd post exactly what's in the string. – Pointy Dec 05 '14 at 21:09
  • You could just do "return message.toString()" inside the function – ryanc1256 Dec 05 '14 at 21:12
  • Is it possible, yes it can be, but what are you trying to do exactly? – epascarello Dec 05 '14 at 21:14
  • http://stackoverflow.com/questions/912596/how-to-turn-a-string-into-a-javascript-function-call – Brian Shamblen Dec 05 '14 at 21:19
  • epascarello, I would like to convert the string back to a function. Brian, I don't want to call an existing function. I would like to convert the entire string into a function. – user1840267 Dec 05 '14 at 21:20
  • @BrianShamblen this is a different question than that one. In that question, they have the name of a function they want to call. – TheDude Dec 05 '14 at 21:21
  • One is forced to question *why* you want to do this. Evaluating arbitrary code is considered dangerous in almost every language that has the ability. – jpmc26 Dec 06 '14 at 02:22

4 Answers4

3

You're nearly there, but you're missing something.

When we call toString() on your function, we get

"function (message) {
    console.log(message);
}"

which we can then eval. However, we're just creating an anonymous function object here; we won't be able to call it!

If we instead to something like:

var functionString = "var restoredFunc = " + function (message) {
    console.log(message);
}.toString();

We can then do the following

eval(functionString);
// prints "hello!" to console
restoredFunc("hello!");
Aaron Hammond
  • 617
  • 4
  • 9
2

Your functionString contains exactly the string

"function (message) { console.log(message); }"

Evaluating it as-is does present JavaScript engine with incorrect syntax (there is no name for this function). JavaScript expects construct like function <name>(<params>) { }. Alternatively, you can use anonymous function (i.e. no name present), but only as a parameter or in a context of evaluating expression. The minimal typical evaluating expression would be (function() {})() If you want to get fancy, !function() {} is also ok - the exclamation mark in front turns it into boolean expression that requires function evaluation before negating the output.

So, in your example this will work:

eval("("+functionString+")('abc')");

because then you do anonymous function call - something JavaScript can live with.

Alternatively, you can also use just brackets, then you need to assign the result to something you can use later:

var foo = eval("("+functionString+")");
foo('ddd');

Here is a little proof / playground to learn about it: http://jsfiddle.net/Exceeder/ydann6b3/

Alex Pakka
  • 9,466
  • 3
  • 45
  • 69
  • Works, thanks! Could you tell me what I should google for to learn more about this, for example the +-wrapping of functionString? – user1840267 Dec 05 '14 at 21:28
  • @user1840267 for eval(), it always makes sense to print the actual string you evaluate, then copy-paste it in the editor of your choice in empty .js file and see if it is syntactically correct. – Alex Pakka Dec 05 '14 at 21:32
  • Ah, I see, he is simply wrapping the function into parenthesis! Got it, thanks! – user1840267 Dec 05 '14 at 21:39
1

yes its possible in JavaScript but you can't eval anonymous function without assignment

So you go through it like so

var functionString = function (message) {
    console.log(message);
}.toString();

eval("myfunction =" + functionString)

myfunction("Hello World!")
tinker
  • 855
  • 1
  • 6
  • 13
1

Your functionString is a string that looks like

"function (message) {
    console.log(message);
}"

You could covert that string to an Immediately-Invoked Function Expression (IIFE) using string concatenation, similar to below.

(function (message) {
        console.log(message);
})("HI!");

and then eval that. Here is the result from Chrome's JavaScript console:

eval('(' + functionString + ')("HI!")')
HI!
Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155