2013-07-21 18 views
6

javascript consente l'aliasing eval? La prima parte del codice seguente si comporta in modo imprevisto (visualizza 1, 1), ma la seconda parte non lo fa (visualizza 1, 2). Un riferimento allo script ECMA o ai documenti di mozilla sarà utile, non sono riuscito a trovarne uno.Javascript eval alias

<html> 
<script type="application/javascript;version=1.8"> 
    (function(){ 
     eval('var testVar=1'); 
     alert(testVar); 
     var eval2=eval; 
     eval2('var testVar=2'); 
     alert(testVar); 
    })(); 

    (function(){ 
     eval('var testVar=1'); 
     alert(testVar); 
     eval('var testVar=2'); 
     alert(testVar); 
    })(); 
</script> 
</html> 
+1

Come è il risultato del primo inaspettato? –

+0

Quando 'eval' non è aliasato, visualizza 1, 2, vedere la seconda funzione. Se è previsto, puoi rispondere alla domanda? Grazie. – simonzack

+0

Sì, ma hai detto che il primo si comporta in modo inaspettato visualizzando 1 e 2. È previsto. –

risposta

7

Non è possibile "alias" eval e si aspettano di comportarsi allo stesso. Semplice come quella. Perché? eval non è una funzione.

Quello che succede è che quando si chiama eval2, si imposta la variabile "cache" per lavorare con le variabili globali. Pertanto, impostando una variabile al suo interno, si imposta una variabile globale. Tuttavia, quando si esce, la variabile "cache" ritorna alla funzione con scope. Ecco perché il secondo alert mostra 1 - la variabile globale viene ombreggiata dal livello di funzione uno.

Questo si segnala cui all'allegato E (pagina 239) di ECMAScript (sottolineatura mia)

10.4.2: Nel Edition 5, chiamate indirette alla funzione eval utilizzano l'ambiente globale come sia il ambiente variabile e ambiente lessicale per il codice eval. Nell'Edizione 3, gli ambienti variabili e lessicali del chiamante di una valutazione indiretta venivano usati come ambienti per il codice eval.

La definizione completa su "Inserimento codice Eval" è definito in §10.5.2 (pagina 58) (sottolineatura mia)

  1. Se non c'è contesto di chiamata o se il codice non è eval essendo valutati da una chiamata diretta (15.1.2.1.1) alla funzione eval poi,
    • inizializzare il contesto di esecuzione come se fosse un contesto di esecuzione globale utilizzando il codice eval come C come descritto in 10.4.1.1 .
  2. Else,
    • Impostare la ThisBinding allo stesso valore del ThisBinding del contesto di esecuzione di chiamata.
    • Impostare il LexicalEnvironment sullo stesso valore di LexicalEnvironment del contesto di esecuzione chiamata .
    • Impostare VariableEnvironment sullo stesso valore di VariableEnvironment del contesto di esecuzione chiamata .
  3. Se il codice eval è rigoroso codice, quindi
    • Let strictVarEnv essere il risultato della chiamata NewDeclarativeEnvironment passando il LexicalEnvironment come argomento.
    • Impostare il LexicalEnvironment su strictVarEnv.
    • Impostare VariableEnvironment su strictVarEnv.
  4. Eseguire l'istanza del binding della dichiarazione come descritto in 10.5 utilizzando il codice eval.
+1

Se 'eval' non è una funzione, perché' alert (eval) 'mostra' function eval() {[codice nativo]} '? – Teemu

+0

La tua prima parte non è corretta, aliasing 'eval' funziona in firefox e non ci sono errori sollevati, ma non come mi aspetto. Prova 'eval2 (alert (" test "))'. In effetti, le specifiche ECMA affermano che "le implementazioni non sono più consentite per limitare l'uso di eval in modi che non sono una chiamata diretta". – simonzack

+3

Stai fraintendendo lo standard. 'eval' * può * essere alias, ma poi funzionerà diversamente. Vedi le altre parti dello standard: "* Il codice Eval è il testo sorgente fornito nella funzione di eval incorporato **." (# 10.1), "* o se il codice di valutazione non viene valutato da un * * chiamata diretta *** "(# 10.4.2) e altri. – DCoder

2

Nel primo caso, quando si utilizza eval, viene utilizzato l'ambito di funzione all'interno del quale viene eseguito. Quando assegni eval a eval2 e poi esegui la stessa istruzione, sembra che stia utilizzando il contesto window (ambito globale) e non il contesto della funzione. Ecco perché si vede lo stesso valore 1 nel primo caso perché testVar all'interno della funzione è di 1 e al di fuori window.testVar è 2. È possibile dimostrare questo eseguendo il seguito frammento

<script> 
(function(){ 
     eval('var testVar=1'); 
     alert(window.testVar); 
     var eval2=eval; 

     eval2('var testVar=2'); 
     alert(window.testVar); 
    })(); 

    (function(){ 
     eval('var testVar=1'); 
     alert(testVar); 
     eval('var testVar=2'); 
     alert(testVar); 
    })(); 
</script> 

In realtà, come per Mozilla Developer Network, si puo' t alias eval.

Problemi correlati