2010-05-03 11 views
12

Tengo un poco de código JavaScript que se especifica en un archivo de configuración en el lado del servidor. Como no puedo especificar una función de JavaScript en el lenguaje de configuración (Lua), la tengo como una cadena. El servidor devuelve la cadena de alguna JSON y tengo el cliente lo interpretan utilizando una función de limpieza:JavaScript eval() "error de sintaxis" al analizar una cadena de función

parse_fields = function(fields) { 
    for (var i = 0; i < fields.length; ++i) { 
     if (fields[i].sortType) { 
      sort_string = fields[i].sortType; 
      fields[i].sortType = eval(sort_string); 
     } 
     return fields; 
    } 
}; 

Así que básicamente es simplemente evalúa sortType si existe. El problema es que Firebug informa un "Error de sintaxis" en la línea eval(). Cuando ejecuto los mismos pasos en la consola Firebug, funciona sin problemas y puedo ejecutar la función como espero. He intentado algunas variaciones diferentes: window.eval en lugar de simple eval, almacenando el sortType como lo hice anteriormente, y probando pequeñas variaciones en la cadena.

Un valor de muestra de fields[i].sortType es "function(value) { return Math.abs(value); }". Aquí está la prueba que hice en la consola de Firebug:

>>> sort_string 
"function(value) { return Math.abs(value); }" 
>>> eval(sort_string) 
function() 
>>> eval(sort_string)(-1) 
1 

y el error en sí en Firebug:

syntax error 
[Break on this error] function(value) { return Math.abs(value); } 

El último bit que puede ser relevante es que todo esto está envuelto en una función Ext JS onReady(), con un cambio de espacio de nombre Ext.ns en la parte superior. Pero asumí que el window.eval llamaría al eval global, independientemente de cualquier posible eval en espacios de nombres más específicos.

Se aprecian todas las ideas.

+3

en cuenta que es decir, puede funciones no eval. – SLaks

+0

intente 'var foo = function (value) {...}' –

+0

@SLaks: 'eval' funciona bien para IE en la cadena anterior, sin errores ... al igual que' eval ("a = function () {return 'b';} ")' - ¿Puedes aclarar lo que quieres decir, por favor? –

Respuesta

37

para hacer lo que quiere, envuelva su cadena entre paréntesis:

a = "function(value) { return Math.abs(value);}"; 
b = eval("("+a+")"); 
b(-1); 
+2

Sí, eso funcionó. ¿Por qué se requieren los paréntesis cuando Firefox ejecuta el código fuera de la interfaz de Firebug, pero no es obligatorio cuando se usa la consola Firebug? –

+0

Yo, por mi parte, no puedo hacer que funcione sin llaves incluso en la consola Firebug. No sé por qué funcionaría para ti. ¿Qué versión de Firebug estás usando? – Jasper

+1

@Kenny Peng: Recuerdo haberme preguntado esto una vez y encontré esta respuesta a una pregunta similar: http://stackoverflow.com/questions/964397/why-does-javascripts-eval-need-parentheses-to-eval-json- data/964437 # 964437. Este fue mi primer pensamiento cuando vi la pregunta, +1 a @jhurshman por su respuesta. –

4

Los paréntesis son necesarios porque obligan a la cosa dentro de ellas para ser evaluados en un contexto de expresión, en la que debe ser una función de la expresión .

Sin los paréntesis, que podría ser en cambio una función declaración, y parece como si a veces está siendo interpretado de esa manera - esto podría ser el origen del extraño comportamiento/incoherente que describes.

comparar esta declaración de la función:

function foo(arg) {} 

con esta función, la expresión:

var funcExpr = function foo(arg) {}; 

También tiene que ser una función de la expresión si no tiene un nombre. Las declaraciones de funciones requieren nombres.

Así que esto no es una declaración válida, porque le falta su nombre:

function (arg) {} 

pero esto es una función de la expresión anónima válida:

var funcExpr = function(arg) {}; 
Cuestiones relacionadas