0

I have a text string that is correctly formatted as a function and I would like to convert it to an actual function. The text string looks like:

function object_123(){
   object_123_Action();
   my_clicked(obj);
}

Apart from the word "function" and {}; all other text is dynamically constructed. i.e. It may never contain object_123_Action(), however, it will be something similar, basic function calls. The only issue will be the obj will need to be the object that the function is assigned to.

Basically, I need:

this.func = eval(func_txt); //to actually work.

Where func_txt is:

function object_123(){
   object_123_Action();
   my_clicked(this);
}
user229044
  • 232,980
  • 40
  • 330
  • 338
Peter
  • 83
  • 9
  • What's the problem with the `eval` call? It actually works when you wrap the `function(){}` in `()`, ie. `eval("(function(a, b){ return a + b; })")(1, 2)`. – skrat Sep 16 '15 at 11:33

5 Answers5

1

Your string contains a function declaration.

When evaluated, it creates a object_123 variable in the scope of eval (which you can then call later) and returns nothing.

If you want to assign the function to this.func then you need to convert the declaration into a function expression. You can do that by wrapping it in parens.

this.func = eval("(" + func_txt ")" );

var func_txt = "function object_123(){\
   object_123_Action();\
   my_clicked(obj);\
}";

this.func = eval("(" + func_txt + ")");
var obj = "...";

function object_123_Action() {
  alert(1);
}

function my_clicked() {
  alert(2);
}


this.func();
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • This was perfect, thank you very much, when I make the changes to pass the object as the param. it works just as I need it - thanks again. – Peter Sep 16 '15 at 13:59
0

You can store your functions in an array on the object. Then, loop though the functions in another function and execute them.

var myObj = { 'myfunctions': [ ] };

and to add functions:

myObj.myFunctions.push (function () { /*function code here*/ });

Or if you already have a named function:

myObj.myFunctions.push (nameOfFunction);

And to call all the functions, use this function (don't add this function to myObj)

function executeMyFunctions (myObj) {
    for (var i = 0; i  < myObj.myFunctions.length; i++) {
        myObj.myFunctions[i]();
    }
}

And if it's possible to avoid using eval, you should.

Community
  • 1
  • 1
0

Try this:

function parseStringToFunction(func) {
    func = func || '(function(){return null;})';
    return (new Function('return ' + func)());
};

var stringifyFunction = '(function(a, b) { return a+b; })';

var callStringifyFunction = parseStringToFunction(stringifyFunction)(1, 2);
alert(callStringifyFunction); // results is 3

Also read this out: detail about eval() and new Function()

Mohit Pandey
  • 3,679
  • 7
  • 26
  • 38
-1

Try this-

$("<script type='text/javascript'></script>").html(func_txt).insertAfter($("script"));
Pankaj Dubey
  • 796
  • 3
  • 8
  • 32
  • Firstly, that's jQuery and the OP doesn't mention jQuery (no jQuery tag). Secondly, that would insert the script after every single script tag, if there are many, and not at all if there are none. – Reinstate Monica Cellio Sep 16 '15 at 11:36
-1

This works:

assert( eval("(function(a, b) { return a+b; })")(1, 2) == 3 )

See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#eval_as_a_string_defining_function_requires_(and)_as_prefix_and_suffix

Simply wrap the function in parens.

skrat
  • 5,518
  • 3
  • 32
  • 48