2009-08-13 27 views
16

Tengo una función y su contenido como una cadena.ejecutando funciones anónimas creadas usando JavaScript eval()

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

Ahora realizo una evaluación() para obtener realmente esa función en una variable.

var func = eval(funcStr); 

Si no recuerdo mal, en Chrome y Opera, simplemente llamando

func(); 

invoca esa función y se muestra la alerta.

Pero, en otros navegadores no era el caso. no pasó nada.

No quiero una discusión sobre cuál es el método correcto, pero ¿cómo puedo hacer esto? Quiero poder llamar a variable(); para ejecutar la función almacenada en esa variable.

+0

Me pregunto por qué necesita una función anónima representada como una cadena literal, en lugar de simplemente tener una función con nombre? –

+0

FYI: Estoy definiendo mi propio script para mi aplicación web. Estoy escribiendo un intérprete y necesito construir funciones JS sobre la marcha y luego crear funciones ejecutables reales a partir de ellas. –

+0

¿por qué no escribirías el intérprete de la manera tradicional? – Breton

Respuesta

30

¿Qué tal esto?

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

Para añadir argumentos a la función:

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

tenga en cuenta que las funciones son objetos y se pueden asignar a cualquier variable, ya que son:

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

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

Esta es una forma elegante de hacerlo, y funciona en todos los navegadores. Gracias :) –

6

Trate

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

eval(funcStr); 

func(); 
+0

hey, ¡Gracias que funcionó! Pero parece un poco extraño hacerlo de esa manera: D. –

4

Utilice la función eval así:

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

Eso es lo que pensé inicialmente, pero estoy bastante seguro de que se aplica solo a los objetos. – karim79

+0

Además, ya sea de la manera correcta o incorrecta ..., no funciona en IE. –

+0

Las funciones también son objetos. Funciona con paréntesis. – Blixt

13

IE no puede eval funciones (Presumiblemente por razones de seguridad).

La mejor solución es poner la función en una matriz, como esto:

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

Heh ... Sneaky sneaky! – Blixt

+0

Sí, puede. Sin embargo, la función literal no son enunciados, por lo que necesitan paréntesis a su alrededor, es más limpia que su solución de matriz –

+1

@Juan: Incorrecta; no puede. Pruebe 'javascript: alert (eval ('(function() {return 3;})'));' – SLaks

0

Lo que también funciona es

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

Comprendo que esto es viejo, pero era el único resultado válido en mis búsquedas de google para evaluar cadenas de funciones de JavaScript anónimas.

Finalmente descubrí cómo hacerlo desde una publicación en el grupo jquery google.

eval("false||"+data) 

donde los datos es la cadena de función como "la función() {return 123;}"

Hasta el momento, solo he probado esto en IE8 y FF8 (los navegadores en mi ordenador personal), pero Creo que jquery usa esto internamente, por lo que debería funcionar en casi todos lados.

+0

No entiendo por qué todos los demás parecen no tener este problema. Esto es oro, gracias! – Shwouchk

0

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

Ejemplo de uso:

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

jaja, me acabas de dar la razón por la cual las aplicaciones empaquetadas de Google no permiten Javascript en línea en el HTML: http://developer.chrome.com/extensions/contentSecurityPolicy.html – nraynaud

0

Un ejemplo simple de definir una función como una cadena, eval() ing ella, y que pasa en un parámetro de tiempo inmediatamente invocar la función (y luego vertido el resultado a la consola):

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

Esto produce una salida como la siguiente.

eval: 12345

3

Hemos resuelto este problema mediante la preparación analizador función universal que permite convertir cadena a verdadera función de 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; 
    }; 
} 

ejemplos de uso:

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 es jsFiddle

Cuestiones relacionadas