56
votes

Say I've got a Javascript string like the following

var fnStr = "function(){blah1;blah2;blah3; }" ;

(This may be from an expression the user has typed in, duly sanitized, or it may be the result of some symbolic computation. It really doesn't matter).

I want to define fn as if the following line was in my code:

var fn = function(){blah1;blah2;blah3; } ;

How do I do that?

The best I've come up with is the following:

var fn = eval("var f = function(){ return "+fnStr+";}; f() ;") ;

This seems to do the trick, even though it uses the dreaded eval(), and uses a slightly convoluted argument. Can I do better? I.e. either not use eval(), or supply it with a simpler argument?

8
Generally eval is evil ;-)Nur Rony

8 Answers

70
votes

There's also the Function object.

var adder = new Function("a", "b", "return a + b");
33
votes

You can do this:

//in your case: eval("var fn = " + fnStr);
eval("var fn = function(){ blah1;blah2;blah3; }"); 
fn();

Not sure how to get it much simpler, sometimes there's no (better) way around eval(). Here's a quick example of this in action.

17
votes

Use parentheses.

var fn = eval("(function() {...})");

This technique is also good for transmitting JSON values.

By the way, it's often better to build functions by composing them directly from other functions. If you are using strings, you have to worry about things like unexpected variable capture.

10
votes

Here's what I use for simple cases:

// an example function
function plus(...args) {
    return args.reduce( (s,v) => s+v, 0 );
}

// function to string
let str = plus.toString();

// string to function
let copy = new Function('return ' + str)();

// tests
console.assert(plus.name == 'plus');
console.assert(copy.name == 'plus');
console.assert(plus.constructor == Function);
console.assert(copy.constructor == Function);
console.assert(plus(1,2,3,4) === copy(1,2,3,4));
console.assert(plus.toString() === copy.toString());
4
votes

You can also insert the string into a script element and then insert the script element into the page.

script_ele = window.document.createElement("script");
script_ele.innerHTML = 'function my_function(){alert("hi!");}';
window.document.body.appendChild(script_ele);
my_function();
3
votes

The Function constructor creates a new Function object. In JavaScript every function is actually a Function object.

// Create a function that takes two arguments and returns the sum of those arguments
var fun = new Function("a", "b", "return a + b");
// Call the function
fun(2, 6);
Output: 8
3
votes

one way:

     var a = 'function f(){ alert(111); } function d(){ alert(222);}';  
     eval(a);
     d();

second more secure way to convert string to a funciton:

     // function name and parameters to pass
    var fnstring = "runMe";
    var fnparams = ["aaa", "bbbb", "ccc"];

    // find object
    var fn = window[fnstring];

    // is object a function?
    if (typeof fn === "function") fn.apply(null, fnparams);


    function runMe(a,b){
      alert(b);
    }

look working code http://plnkr.co/edit/OiQAVd9DMV2PfK0NG9vk

2
votes

You can call Parse your string as javascript fuction

  1. function getDate(){alert('done')} // suppose this is your defined function

to call above function getDate() is this in string format like 'getDate()'

  1. var callFunc=new Function('getDate()') //Parse and register your function

  2. callFunc() // Call the function