2009-08-13 9 views
16

J'ai une fonction et son contenu sous forme de chaîne.exécution de fonctions anonymes créées avec JavaScript eval()

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

Maintenant, je fais un eval() pour obtenir réellement cette fonction dans une variable.

var func = eval(funcStr); 

Si je me souviens bien, dans Chrome et Opera, il suffit d'appeler

func(); 

argué du fait que la fonction et l'alerte a été affichée.

Mais, dans d'autres navigateurs, ce n'était pas le cas. rien ne s'est passé.

Je ne veux pas d'argument quant à la méthode correcte, mais comment puis-je faire cela? Je veux pouvoir appeler variable(); pour exécuter la fonction stockée dans cette variable.

+0

Je me demande pourquoi vous avez besoin d'une fonction anonyme représentée comme un littéral de chaîne, par opposition à simplement avoir une fonction nommée? –

+0

FYI: Je définis mon propre script pour mon application web. J'écris un interpréteur et ai besoin de construire des fonctions de JS à la volée et ensuite créer des fonctions exécutables réelles hors d'elles. –

+0

pourquoi n'écririez-vous pas l'interprète de la manière traditionnelle? – Breton

Répondre

30

Comment cela?

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

Pour ajouter des arguments à la fonction:

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

Prenez note que les fonctions sont des objets et peuvent être affectés à une variable car ils sont:

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

function executeSomething(something) { 
    something(); 
} 
executeSomething(otherFunc); // Alerts 'hello' 
+0

Ceci est à la fois un moyen élégant de le faire, et fonctionne dans tous les navigateurs. Merci :) –

6

Essayez

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

eval(funcStr); 

func(); 
+0

hey, Merci qui a fonctionné! Mais il semble un peu étrange de le faire de cette façon: D. –

4

Utilisez le eval comme ceci:

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

C'est ce que je pensais au départ, mais je suis sûr que cela ne s'applique qu'aux objets. – karim79

+0

Aussi, que ce soit la bonne ou la mauvaise façon ..., cela ne fonctionne pas dans IE. –

+0

Les fonctions sont également des objets. Cela fonctionne avec des parenthèses. – Blixt

13

IE ne peut pas eval fonctions (Vraisemblablement pour des raisons de sécurité).

La meilleure solution est de mettre la fonction dans un tableau, comme ceci:

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

Heh ... Sneaky sournois! – Blixt

+0

Oui, c'est possible. Cependant, les littéraux de fonction ne sont pas des instructions, donc ils ont besoin de parenthèses autour d'eux, c'est plus propre que votre solution de tableau –

+1

@Juan: Wrong; ça ne peut pas. Essayez 'javascript: alert (eval ('(function() {return 3;})'));' – SLaks

0

Ce qui fonctionne aussi est

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

Je sais que c'est vieux, mais il était le seul résultat valide à venir dans mes recherches google pour l'évaluation des chaînes de fonction javascript anonymes.

J'ai finalement trouvé comment le faire à partir d'un post sur le groupe jQuery google.

eval("false||"+data) 

où les données est votre chaîne de fonction comme "function() {return 123;}"

Jusqu'à présent, je n'ai essayé dans IE8 et FF8 (les navigateurs sur mon ordinateur personnel), mais Je crois que jquery utilise cela en interne, donc cela devrait fonctionner à peu près partout.

+0

Je ne comprends pas pourquoi tout le monde semble ne pas avoir ce problème. C'est de l'or, merci! – Shwouchk

0

EVAL sans 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 
} 

Exemple d'utilisation:

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

haha, vous venez de me donner la raison pour laquelle Google Packaged Apps interdire javascript en ligne dans le HTML: http://developer.chrome.com/extensions/contentSecurityPolicy.html – nraynaud

0

Un exemple simple de définir une fonction en tant que chaîne, eval() ing, et le passage d'un paramètre alors que immédiatement appel à la fonction (et le déversement, alors le résultat de la console):

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

Cela produit la sortie suivante.

eval: 12345

3

Nous avons résolu ce problème en préparant l'analyseur de fonction universelle qui convertissent chaîne en fonction réelle JavaScript:

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

here est jsFiddle

Questions connexes