2013-07-21 13 views
6

Javascript aliasing değerlendirmesine izin veriyor mu? Aşağıdaki kodun ilk kısmı beklenmedik şekilde davranır (1, 1 görüntülenir), ancak ikinci kısımda (1, 2 görüntülenir) görüntülenmez. ECMA komut dosyasına veya mozilla dokümanlarına bir referans yardımcı olacaktır, ben bulamadım.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

Birincisi nasıl beklenmiyor? –

+0

"eval" takmadığında, 1, 2 görüntülenir, ikinci işleve bakın. Beklenirse, soruya cevap verebilir misiniz? Teşekkürler. – simonzack

+0

Evet ama ilkinin 1 ve 2 göstererek beklenmedik şekilde davrandığını söylediniz. Bu bekleniyor. –

cevap

7

yapamazsınız "takma" eval ve aynı davranmasını bekliyoruz. Bu kadar basit. Niye ya? eval bir işlev değil.

Neler oluyor, eval2 numaralı telefonu aradığınızda, global değişkenlerle çalışmak için "önbellek" değişkenini ayarlıyorsunuz. Bu nedenle, içinde bir değişken belirleyerek, bir global değişken ayarlıyorsunuz. Bununla birlikte, çıktıktan sonra, "önbellek" değişkeni, kapsamdaki fonksiyona geri döner. Bu yüzden ikinci alert 1'i gösterir - global değişken, işlev seviyesi bir tarafından gölgeleniyor.

Bu

Ek E ECMAScript (vurgu mayın) ait (sayfa 239)

10.4.2 not edilir: Edition'da 5'te, eval işlevi için dolaylı görüşmeleri olarak küresel çevreyi kullanmak hem değişken ortamı ve değerlendirme kodu için sözcüksel ortam. 3. Baskıda, dolaylı değerlendirmenin arayıcı değişken ve sözcük ortamları, değerlendirme kodunun ortamları olarak kullanılmıştır.

hiçbir arama bağlam veya varsa eval kodu değilse "Eval Kodunu Girme" tam tanımı §10.5.2 (sayfa 58) (vurgu benim)

  1. tanımlanan

Bu ise, daha sonra Eval fonksiyonuna, bir doğrudan (15.1.2.1.1) tarafından değerlendirilmektedir

  • yürütme kapsamını initialism 10.4.1.1 de tarif edildiği gibi C Eval kodunu kullanarak küresel yürütme içeriği . Başka
  • ,
    • arama yürütme bağlamının ThisBinding aynı değere ThisBinding ayarlayın.
    • LexicalEnvironment öğesini çağıran yürütme işlevi içeriğinin LexicalEnvironment değeriyle aynı değere ayarlayın.
    • VariableEnvironment öğesini çağıran yürütme içeriğinin VariableEnvironment ile aynı değere ayarlayın. eval kod sıkı kod ise
  • ardından
    • Let NewDeclarativeEnvironment argüman olarak LexicalEnvironment geçen çağırarak sonucu strictVarEnv.
    • LexicalEnvironment öğesini strictVarEnv olarak ayarlayın.
    • VariableEnvironment öğesini strictVarEnv olarak ayarlayın.
  • Değerlendirme kodunu kullanarak 10.5'te açıklandığı gibi Beyan Bağlama Örnekleme gerçekleştirin.
  • +1

    Eğer "eval" bir işlev değilse, neden "alert (eval)" işlevi "işlevini gösterir"() {[native code]} '? – Teemu

    +0

    İlk bölümünüz yanlış, "eval" takma adı firefox'ta çalışıyor ve hiçbir hata olmadı, ancak beklediğim gibi değil. Eval2 (alert ("test")) 'ı deneyin. Aslında, ECMA tarafından yapılan açıklamada, “Uygulamaların, değerlendirmenin kullanımını doğrudan arama yapmayan yollarla kısıtlamalarına izin verilmemektedir.” Ek olarak. – simonzack

    +3

    Standardı yanlış okudunuz. "eval" * takma ad olabilir, ancak daha sonra farklı çalışır. Standardın diğer kısımlarına bakınız: "* Eval, ** built-in eval işlevine sağlanan kaynak metindir. ***" (# 10.1), "* veya eğer eval kodu bir tarafından değerlendirilmiyorsa * * doğrudan arama *** "(# 10.4.2) ve diğerleri. – DCoder

    2

    İlk durumda, eval'u kullandığınızda, içinde yürütüldüğü işlev kapsamını kullanır. eval için eval2 atayıp daha sonra aynı deyimi çalıştırdığınızda, işlev bağlamında değil, window bağlamı (genel kapsam) kullanıyor görünmektedir. İlk durumda aynı değeri 1'e bakın neden işlevi içinde testVar 1 ve window.testVar dışında Sen yürüterek bu kanıtlayabilirim 2. olduğunu That 'yapabilirsiniz, Mozilla Developer Network uyarınca aşağıda, Aslında

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

    pasajı var t alias eval.