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.

  • I am wondering why you need an anonymous function represented as a string literal, as opposed to simply having a named function? – Russ Cam Aug 13 '09 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. –  Aug 13 '09 at 12:03
  • why wouldn't you write the interpreter in the traditional way? – Breton Aug 13 '09 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. –  Aug 13 '09 at 12:45
  • 3
    Try wrapping the function in parentheses before passing the string into `eval`. ```var funcStr = "( function() { alert('hello'); } )";``` – awhie29urh2 Jul 02 '13 at 01:16
  • @PeopleAskingWhy? -- Because I want to learn the limitations of the language, and explore its outter edges, so I understand it well enough that instead of asking these questions, I know how to answer them. – Mike Aug 25 '23 at 15:11

11 Answers11

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'
Blixt
  • 49,547
  • 13
  • 120
  • 153
  • 1
    This is both an elegant way to do it, and works in all browsers. Thanks :) –  Aug 13 '09 at 12:10
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];
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Yes it can. However, function literal are not statements, so they need parentheses around them, it's cleaner than your array solution – Ruan Mendes Jan 05 '11 at 02:04
  • 3
    @Juan: Wrong; it cannot. Try `javascript:alert(eval('( function() { return 3; } )'));` – SLaks Jan 05 '11 at 02:06
  • My bad, I suggested using parentheses instead of your array solution, I didn't realize that didn't work in IE – Ruan Mendes Jan 05 '11 at 02:07
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.

user319862
  • 1,797
  • 2
  • 24
  • 32
6

Try

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

eval(funcStr);

func();
AutomatedTester
  • 22,188
  • 7
  • 49
  • 62
David Henderson
  • 1,185
  • 1
  • 10
  • 16
  • hey, Thanks that worked! But it looks a bit weird to do it that way :D. –  Aug 13 '09 at 12:02
4

Use the eval like this :

var func = eval('(' + funcStr + ')');
Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
  • That's what I thought initially, but I'm pretty sure that applies only to objects. – karim79 Aug 13 '09 at 12:06
  • Also, whether its the right way or the wrong way..., it doesn't work in IE. –  Aug 13 '09 at 12:08
  • 1
    Tried this on IE and didn't work `eval ('(function(){return 'Yay'})')()`. However, `eval ('[function(){return 'Yay'}][0]')()` worked – Ruan Mendes Jan 05 '11 at 02:09
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

Mr. Pumpkin
  • 6,212
  • 6
  • 44
  • 60
1

This is also ok.

var func = eval("_="+funcStr);
gogog
  • 410
  • 5
  • 9
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

awhie29urh2
  • 15,547
  • 2
  • 19
  • 20
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);
Ferdinand Liu
  • 314
  • 1
  • 3
  • haha, you just gave me the reason why Google Packaged Apps disallow inline javascript in the HTML: http://developer.chrome.com/extensions/contentSecurityPolicy.html – nraynaud Dec 01 '13 at 22:30
-1

What also works is

var myFunc = function(myParam){
   // function body here
}
Zoidberg
  • 10,137
  • 2
  • 31
  • 53
-1

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

Brad Koch
  • 19,267
  • 19
  • 110
  • 137
gx0r
  • 4,682
  • 2
  • 23
  • 24