2010-05-03 4 views
12

Ho un po 'di codice JavaScript specificato in un file di configurazione sul lato server. Dal momento che non posso specificare una funzione JavaScript nel linguaggio di configurazione (Lua), l'ho come stringa. Il server restituisce la stringa in qualche JSON e ho il cliente interpretarla utilizzando una funzione di clean-up:JavaScript eval() "errore di sintassi" durante l'analisi di una stringa di funzioni

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; 
    } 
}; 

Quindi, fondamentalmente solo valuta sortType se esiste. Il problema è che Firebug sta segnalando un "Errore di sintassi" sulla riga eval(). Quando eseguo gli stessi passaggi sulla console di Firebug, funziona senza problemi e posso eseguire la funzione come previsto. Ho provato alcune varianti diverse: window.eval invece del semplice eval, archiviando lo sortType come ho fatto sopra e provando piccole variazioni alla stringa.

Un valore di esempio di fields[i].sortType è "function(value) { return Math.abs(value); }". Ecco il test che ho fatto in console Firebug:

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

e l'errore in sé in Firebug:

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

L'ultimo bit che possono essere rilevanti è che tutto questo è avvolto in una funzione di Ext JS onReady(), con una modifica dello spazio dei nomi Ext.ns nella parte superiore. Ma supponevo che lo window.eval chiamasse lo eval globale, indipendentemente da qualsiasi possibile eval in spazi dei nomi più specifici.

Tutte le idee sono apprezzate.

+3

notare che IE può funzioni non eval. – SLaks

+0

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

+0

@SLaks: 'eval' funziona bene per me in IE per la stringa sopra, senza errori ... così come' eval ("a = function () {return 'b';} ")' - puoi chiarire cosa intendi per favore? –

risposta

37

di fare quello che vuoi, avvolgere la stringa tra parentesi:

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

Sì, ha funzionato. Perché sono necessarie le parentesi quando Firefox esegue il codice all'esterno dell'interfaccia Firebug, ma non è necessario quando si utilizza la console Firebug? –

+0

Io, per esempio, non riesco a farlo funzionare senza le parentesi anche nella console di Firebug. Non so perché potrebbe funzionare per te. Quale versione di Firebug stai usando? – Jasper

+1

@Kenny Peng: Ricordo di essermi chiesto una volta questa cosa e ho trovato questa risposta a una domanda simile: http://stackoverflow.com/questions/964397/why-does-javascripts-eval-need-parentheses-to-eval-json- dati/964.437 # 964.437. Questo è stato il mio primo pensiero quando ho visto la domanda, +1 a @jhurshman per la sua risposta. –

4

Le parentesi sono necessari perché costringono la cosa al loro interno da valutare in un contesto di espressione, dove deve essere una funzione-espressione .

Senza le parentesi, potrebbe invece essere una funzione dichiarazione, e sembra come se a volte si viene analizzato in questo modo - questa potrebbe essere la fonte del comportamento strano/incoerente si sta descrivendo.

paragonare questa dichiarazione di funzione:

function foo(arg) {} 

con questa funzione-espressione:

var funcExpr = function foo(arg) {}; 

Si deve anche essere una funzione di espressione, se non ha un nome. Le dichiarazioni di funzione richiedono nomi.

Quindi questa non è una dichiarazione valida, perché manca il suo nome:

function (arg) {} 

ma questa è una valida, anonima funzione di espressione:

var funcExpr = function(arg) {}; 
Problemi correlati