Is there a way to create a function from a string with javascript?

83,843

Solution 1

I added a jsperf test for 4 different ways to create a function from string :

  • Using RegExp with Function class

    var func = "function (a, b) { return a + b; }".parseFunction();

  • Using Function class with "return"

    var func = new Function("return " + "function (a, b) { return a + b; }")();

  • Using official Function constructor

    var func = new Function("a", "b", "return a + b;");

  • Using Eval

    eval("var func = function (a, b) { return a + b; };");

http://jsben.ch/D2xTG

2 result samples: enter image description here enter image description here

Solution 2

A better way to create a function from a string is by using Function:

var fn = Function("alert('hello there')");
fn();

This has as advantage / disadvantage that variables in the current scope (if not global) do not apply to the newly constructed function.

Passing arguments is possible too:

var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'

Solution 3

You're pretty close.

//Create string representation of function
var s = "function test(){  alert(1); }";

//"Register" the function
eval(s);

//Call the function
test();

Here's a working fiddle.

Solution 4

Yes, using Function is a great solution but we can go a bit further and prepare universal parser that parse string and convert it 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

Solution 5

Dynamic function names in JavaScript

Using Function

var name = "foo";
// Implement it
var func = new Function("return function " + name + "(){ alert('hi there!'); };")();
// Test it
func();
// Next is TRUE
func.name === 'foo'

Source: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/

Using eval

var name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'

Using sjsClass

https://github.com/reduardo7/sjsClass

Example

Class.extend('newClassName', {
    __constructor: function() {
        // ...
    }
});

var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'
Share:
83,843
ymutlu
Author by

ymutlu

The belief that great experiences build great businesses.

Updated on March 08, 2020

Comments

  • ymutlu
    ymutlu about 4 years

    For example;

    var s = "function test(){
      alert(1);
    }";
    
    var fnc = aMethod(s);
    

    If this is the string, I want a function that's called fnc. And fnc(); pops alert screen.

    eval("alert(1);") doesnt solve my problem.

  • ymutlu
    ymutlu over 12 years
    i knew that the function was declared, but couldnt guess to call function name. Thanks alot.
  • Christian C. Salvadó
    Christian C. Salvadó over 12 years
    Agree, with Function you don't pollute the local scope and this is why eval makes optimization so hard for engines... With the OP example, I would: var fnc = Function('return '+s)();
  • Bryan Rayner
    Bryan Rayner almost 9 years
    I think this probably should be the accepted answer. It's much safer than eval().
  • Ryan Griggs
    Ryan Griggs about 8 years
    You, my friend, deserve many upvotes. This has the advantage of creating a function object which can be assigned to events, etc. For example: element.onclick = Function("alert('test');");
  • Lekensteyn
    Lekensteyn about 8 years
    @RyanGriggs In your case you do not need the "eval" functionality so it is better written as element.onclick = function() { alert("test"); }.
  • Ryan Griggs
    Ryan Griggs about 8 years
    You are correct from my example. However, if you wanted to assign arbitrary functions stored in strings, your method is perfect. This is what I'm actually trying to do. I have multiple functions stored in string variables, and want to assign one to an onclick action.
  • phnah
    phnah about 8 years
    @KthProg Chill down ;). It's not always bad, like this situation, the jsperf is down at the moment, luckily I added the result screenshots before it was down, when I got the comment from Bulk.
  • Dan Smith
    Dan Smith about 8 years
    @KthProg FYI this was a canned response generated by the moderation system :) it pops up in a queue and we check for predetermined problems, one of which this comment is designed to fix. It's not a hard and fast rule, and you'll notice the comment is in the form of a suggestion not a command.
  • Admin
    Admin over 7 years
    Obligatory eval warning to future searchers: eval can open loopholes for hackers: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… but if you know its dangers and can avoid them, then this is a nice simple way to create a function from a string
  • Marcel Djaman
    Marcel Djaman over 5 years
    what if you don't have the name of function since it came from a database record?
  • sathish kumar
    sathish kumar about 5 years
    hi please support arrow function support to this method?
  • Cegone
    Cegone over 4 years
    I'm receiving this error in typescirpt "Property 'parseFunction' does not exist on type 'String'."
  • Дмитрий Васильев
    Дмитрий Васильев over 4 years
    Thanks. Very interesting