2011-10-16 12 views
5

Per l'applicazione Javascript, devo essere in grado di consentire all'utente di salvare lo stato di un oggetto. Ciò comporta il salvataggio di una serie di funzioni personalizzate precedentemente create dinamicamente o tramite una GUI e il caricamento di queste funzioni memorizzate in seguito. Essenzialmente ho bisogno di serializzare e unserializzare le funzioni.Operazione inversa per Function.toString()

In questo momento mi raggiungere la parte serialize utilizzando il metodo dell'oggetto Function .toString():

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

Questo mi dà funzioni "serializzati" come questa bellezza (si noti che la funzione è senza nome):

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

deserializzazione, questo è dove faccio fatica. Il mio migliore soluzione attuale per le funzioni di deserializzazione, è questo:

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

Nota come ho anteporre la funzione serializzato con t = prima di chiamare eval() su di esso. Non mi piace farlo perché crea una variabile globale ma non riesco a trovare una soluzione. Quando non è anteponendo questo, ricevo un "SyntaxError: token imprevisto (". Quando anteponendo var t =, eval() non restituisce la funzione ma undefined

ci sono modi alternativi per "unserialize" una funzione senza nome

.?

PS: Sono a conoscenza delle implicazioni sulla sicurezza dell'utilizzo di eval() sull'input dell'utente.Per il futuro prevedibile sono l'unico utente di questo software, quindi questo è attualmente un problema

risposta

6

È possibile utilizzare la funzione costruttore per evitare di creare una variabile globale:

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

Ciò equivale a:

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

Una cosa da stare attenti è la chiusura circostante, che non sarà in grado di catturare, in modo da variabili all'interno della funzione sarà "cambiamento" quando si serializzare e de- serializzare.

modificare

Non sto pensando, è possibile naturalmente solo fare:

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

La chiusura è preso cura di. Queste funzioni sono sempre eseguite usando 'Function.call (theContextTheFunctionIsExecutedIn)'. A parte questo, il tuo suggerimento di circondare la funzione serializzata con le parentesi funziona - sai perché? – jonemo

+1

In base a [MDN] (https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope), l'aggiunta dei parenti la modifica da una funzione * dichiarazione * a una funzione * espressione *. (Fa parte di un'espressione nei parens). Poiché è un'espressione, restituirà un valore che è possibile assegnare a 'func'. Questo potrebbe anche dipendere dall'ambito in cui si trova attualmente l'eval. –

+0

Vedi anche http://kangax.github.com/nfe/ – user123444555621

0

Questo dovrebbe funzionare:

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