web-dev-qa-db-fra.com

Est-il possible de créer une fonction à partir d'une chaîne de caractères avec javascript?

Par exemple;

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

var fnc = aMethod(s);

Si c'est la chaîne, je veux une fonction qui s'appelle fnc. Et fnc(); apparaît l'écran d'alerte.

eval("alert(1);") ne résout pas mon problème.

89
ymutlu

J'ai ajouté un test jsperf pour 4 façons différentes de créer une fonction à partir de chaîne:

  • Utilisation de RegExp avec la classe de fonction

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

  • Utilisation de la classe de fonction avec "return"

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

  • Utilisation du constructeur de fonction officiel

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

  • Utiliser Eval

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

http://jsben.ch/D2xTG

2 échantillons de résultats: enter image description hereenter image description here

50
phnah

Un meilleur moyen de créer une fonction à partir d'une chaîne consiste à utiliser Function:

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

Cela a pour avantage/inconvénient que les variables de l'étendue actuelle (si elles ne sont pas globales) ne s'appliquent pas à la fonction nouvellement construite.

Passer des arguments est également possible:

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

Tu es assez proche.

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

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

//Call the function
test();

Voici n violon qui travaille .

38
James Hill

Oui, utiliser Function est une excellente solution, mais nous pouvons aller un peu plus loin et préparer un analyseur universel qui analyse la chaîne et la convertit en une fonction JavaScript réelle ...

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;
    };
}

exemples d'utilisation:

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();

ici est jsfiddle

13
Mr. Pumpkin

Noms de fonctions dynamiques dans JavaScript

Utiliser 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/

Utiliser eval

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

Utiliser sjsClass

https://github.com/reduardo7/sjsClass

Exemple

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

var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'
11
Eduardo Cuomo

Cette technique peut être finalement équivalente à la méthode eval, mais je voulais l’ajouter car elle pourrait être utile pour certains.

var newCode = document.createElement("script");

newCode.text = "function newFun( a, b ) { return a + b; }";

document.body.appendChild( newCode );

Cela ressemble fonctionnellement à l’ajout de cet élément <script> à la fin de votre document, par exemple:

...

<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>

</body>
</html>
5
David Newberry

Utilisez la new Function() avec un retour à l'intérieur et exécutez-le immédiatement.

var s = `function test(){
  alert(1);
}`;

var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()
2
Fernando Carvajal

Un exemple avec des arguments dynamiques:

let args = {a:1, b:2}
  , fnString = 'return a + b;';

let fn = Function.apply(Function, Object.keys(args).concat(fnString));

let result = fn.apply(fn, Object.keys(args).map(key=>args[key]))
0
brunettdan