2012-07-27 11 views
5

So che eval e setTimeout è possibile accettare una stringa come parametro (1 °) e so che è meglio non utilizzarlo. Sono solo curioso perché c'è una differenza:Differenza tra eval e setTimeout esegue il codice stringa

!function() { 
    var foo = 123; 
    eval("alert(foo)"); 
}(); 

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

il primo avrebbe funzionato, e il secondo darà un errore: foo is not defined

Come sono eseguiti dietro la scena?

+1

non va fuori campo prima che venga richiamato il callback setTimeout? –

+1

Perché scherzare con cose malvagie ^^ Non usare nessuno di questi :) – Andreas

+0

Un punto di vista correlato interessante [qui] (https://stackoverflow.com/q/3492015/465053). – RBT

risposta

4

Vedere le reference of setTimeout on MDN.

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

Al contrario, la stringa letterale passata a eval() viene eseguito nel contesto della chiamata a eval.

+0

e il codice passato a 'eval' verrà eseguito nel contesto in cui' eval' è in esecuzione? – wong2

+0

Esatto, la stringa letterale è valutata "sul posto" e ha accesso alle variabili definite in quel contesto. – Wolfram

+0

@ wong2 in realtà dipende da come si chiama 'eval'. Nei browser moderni, la seguente eval è in ambito globale: http://jsfiddle.net/4p9QY/ perché è una valutazione indiretta. Ecco altri esempi di chiamate eval indirette http://perfectionkills.com/global-eval-what-are-the-options/#indirect_eval_call_examples – Esailija

2

setTimeout eval è inoltre eseguito in ambito globale, quindi non è a conoscenza di foo.

Ecco reference una copia di backup:

String literals are evaluated in the global context, so local symbols in the context where setTimeout() was called will not be available when the string is evaluated as code.

0
!function() { 
    var foo = 123; 
    eval("alert(foo)"); 
}(); 

Quando si esegue questo codice, javascript farà finta che la riga 3 dica "avviso (pippo)". Foo è definito nell'ambito della funzione.

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

Quando si esegue questo codice, javascript inserirà una nuova funzione; vale a dire function() {alert(foo)}. Nell'ambito di questa "nuova" funzione, foo non è definito.

1

setTimeout accetta più parametri rispetto al riferimento alla funzione e al timeout. Tutto ciò che viene inserito dopo il timeout verrà passato alla tua funzione come parametro.

setTimeout(myFunction(param1, param2), 0, param1, param2); 
0

Come complemento alla risposta corretta, ecco una chiamata a eval, che vi darà lo stesso comportamento, e l'errore in questi casi:

!function() { 
    var foo = 123; 
    window.eval("alert(foo)"); // <- note the window.eval, this is important and changes the behavior of the `eval` function 
}(); 

!function() { 
    var foo = 123; 
    setTimeout("alert(foo)", 0); 
}(); 

Questo post del blog va in profondità sul diversi tipi di eval: http://perfectionkills.com/global-eval-what-are-the-options/

Problemi correlati