2011-10-16 8 views
5

Para la aplicación de JavaScript, necesito poder permitir al usuario guardar el estado de un objeto. Esto implica guardar un conjunto de funciones personalizadas que se crearon previamente dinámicamente o mediante una GUI, y cargar estas funciones almacenadas más adelante. Esencialmente necesito serializar y deserializar funciones.Operación inversa para la función de Javascript.toString()

Ahora mismo alcanzar la parte serializar utilizando el método del objeto Función .toString():

func.toString().replace('"', '\"').replace(/(\r)/g, ' ').replace(/(\n)/g, ' ').replace(/(\t)/g, ' ') 

Esto me da funciones "en serie" como esta belleza (tenga en cuenta que la función no tiene nombre):

"function (someParameter) {this.someFunctionName(return 'something';}" 

Deserializando esto es donde lucho. Mi actual mejor solución para revertir la seriación de las funciones es la siguiente:

var func = eval('t =' + so.actions[i].func); 

Nota cómo la función de Prefijo serializado con t = antes de llamar eval() en él. No me gusta hacer esto porque crea una variable global, pero no puedo encontrar una forma de evitarlo. Cuando no anteponiendo esto, recibo un "SyntaxError: símbolo inesperado (". Cuando anteponiendo var t =, eval() no devuelve la función pero undefined

¿Existen formas alternativas para una función sin nombre "unserialize"

.?

PD: Soy consciente de las implicaciones de seguridad de usar eval() en la entrada del usuario. En el futuro previsible, soy el único usuario de este software, por lo que actualmente no es un problema

Respuesta

6

Puede usar la función constructor para evitar la creación de una variable global:

var func = Function("return " + so.actions[i].func)(); 

Esto es equivalente a:

var func = eval("(function() { return " + so.actions[i].func + " })()"); 

Una cosa a tener cuidado de no es el cierre de los alrededores, que usted no será capaz de capturar, por lo que las variables dentro de la función se "cambio" cuando serializar y de- publicar por fascículos.

edición

No estoy pensando, por supuesto, puedes simplemente hacer:

var func = eval("(" + so.actions[i].func + ")"); 
+0

El cierre está cuidado. Estas funciones solo se ejecutan utilizando 'Function.call (theContextTheFunctionIsExecutedIn)'. Dejando de lado su sugerencia de rodear la función serializada con corchetes, ¿sabe por qué? – jonemo

+1

De acuerdo con [MDN] (https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope), agregar los paréntesis lo cambia de una función * declaration * a una función * expression *. (Es parte de una expresión en los parens). Dado que es una expresión, devolverá un valor que puede asignar a 'func'. Esto también podría depender del alcance en el que eval esté actualmente. –

+0

Vea también http://kangax.github.com/nfe/ – user123444555621

0

Esto debería funcionar:

eval('var func = ' + so.actions[i].func); 
Cuestiones relacionadas