20

I have a function and its contents as a string.

var funcStr = "function() { alert('hello'); }";

Now, I do an eval() to actually get that function in a variable.

var func = eval(funcStr);

If I remember correctly, in Chrome and Opera, simply calling

func();

invoked that function and the alert was displayed.

But, in other browsers it wasn't the case. nothing happened.

I don't want an arguement about which is the correct method, but how can I do this? I want to be able to call variable(); to execute the function stored in that variable.

6
  • I am wondering why you need an anonymous function represented as a string literal, as opposed to simply having a named function? Commented Aug 13, 2009 at 12:02
  • FYI: I am defining my own script for my web app. I am writing an interpreter and need to construct JS functions on the fly and then create actual executable functions out of them. Commented Aug 13, 2009 at 12:03
  • why wouldn't you write the interpreter in the traditional way? Commented Aug 13, 2009 at 12:39
  • 1
    I don't know how to write it in the "traditional way".. I found this easier. If you can clue me in to how its done "traditionally" it'd be nice. Commented Aug 13, 2009 at 12:45
  • 3
    Try wrapping the function in parentheses before passing the string into eval. var funcStr = "( function() { alert('hello'); } )"; Commented Jul 2, 2013 at 1:16

11 Answers 11

34

How about this?

var func = new Function('alert("hello");');

To add arguments to the function:

var func = new Function('what', 'alert("hello " + what);');
func('world'); // hello world

Do note that functions are objects and can be assigned to any variable as they are:

var func = function () { alert('hello'); };
var otherFunc = func;
func = 'funky!';

function executeSomething(something) {
    something();
}
executeSomething(otherFunc); // Alerts 'hello'
Sign up to request clarification or add additional context in comments.

3 Comments

This is both an elegant way to do it, and works in all browsers. Thanks :)
But this new Function() is not CSP compliant. @Blixt, any CSP compliant approach for this?
@GibranMohammadKhan It will depend on your setup, but some options are to run the JavaScript in an iframe that allows execution from blob: URLs, and store your generated JS as such, or if you want to get really advanced you can use Service Workers to serve dynamic JS from the actual domain (from the perspective of the browser, even if it's all local) but in my experience it's really not worth it.
15

IE cannot eval functions (Presumably for security reasons).

The best workaround is to put the function in an array, like this:

var func = eval('[' + funcStr + ']')[0];

3 Comments

Yes it can. However, function literal are not statements, so they need parentheses around them, it's cleaner than your array solution
@Juan: Wrong; it cannot. Try javascript:alert(eval('( function() { return 3; } )'));
My bad, I suggested using parentheses instead of your array solution, I didn't realize that didn't work in IE
8

I realize this is old, but it was the only valid result coming up in my google searches for evaluating anonymous javascript function strings.

I finally figured out how to do it from a post on the jquery google group.

eval("false||"+data)

where data is your function string like "function() { return 123; }"

So far, I have only tried this in IE8 and FF8 (the browsers on my personal computer), but I believe jquery uses this internally so it should work just about everywhere.

2 Comments

I don't understand why everyone else is seems to not have this issue. This is gold, thanks!
We can do it also on this way eval('!1||'+funcBody);
6

Try

var funcStr = "var func = function() { alert('hello'); }";

eval(funcStr);

func();

1 Comment

hey, Thanks that worked! But it looks a bit weird to do it that way :D.
4

Use the eval like this :

var func = eval('(' + funcStr + ')');

3 Comments

That's what I thought initially, but I'm pretty sure that applies only to objects.
Also, whether its the right way or the wrong way..., it doesn't work in IE.
Tried this on IE and didn't work eval ('(function(){return 'Yay'})')(). However, eval ('[function(){return 'Yay'}][0]')() worked
4

We solved this problem by preparing universal function parser that convert string to real JavaScript function:

if (typeof String.prototype.parseFunction != 'function') {
    String.prototype.parseFunction = function () {
        var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
        var match = funcReg.exec(this.replace(/\n/g, ' '));

        if(match) {
            return new Function(match[1].split(','), match[2]);
        }

        return null;
    };
}

examples of usage:

var func = 'function (a, b) { return a + b; }'.parseFunction();
alert(func(3,4));

func = 'function (a, b) { alert("Hello from function initiated from string!"); }'.parseFunction();
func();

here is jsfiddle

1 Comment

You're a genius! With some modifications to strip comments your function saved my day, thank you so much.
1

This is also ok.

var func = eval("_="+funcStr);

Comments

0

EVAL without eval()...

function evalEx(code){
  var result,D=document,S=D.createElement('script'),
  H=D.head||D.getElementsByTagName['head'][0],
  param=Array.prototype.slice.call(arguments);
  code='function evalWE(){'+code+'}';
  S.innerText===''?S.innerText=code:S.textContent=code;
  H.appendChild(S);
  result=evalWE.apply(this,param);
  H.removeChild(S);
  return result
}

Usage Example:

ABC=evalEx('return "ABC"');
nine=evalEx('return arguments[1]+arguments[2]',4,5);

1 Comment

haha, you just gave me the reason why Google Packaged Apps disallow inline javascript in the HTML: developer.chrome.com/extensions/contentSecurityPolicy.html
0

A simple example of defining a function as a string, eval()ing it, and passing in a parameter while immediately invoking the function (and then dumping the result to the console):

console.log('eval: %s', eval("(function(foo) { return foo.bar; })")({"bar": "12345"}));

This produces output like the following.

eval: 12345

Comments

-1

What also works is

var myFunc = function(myParam){
   // function body here
}

Comments

-1

function-serialization-tools provides a function, s2f(), that takes a string representation of a function and returns it as a function.

Comments