主題:javascript進階之變數篇–轉載http://www.javaeye.com/topic/19506

來源:互聯網
上載者:User
仔細的看了看<javascript權威指南>,算筆記吧
1、關於變數的聲名
大家都知道javascript是可以隱式聲名變數的。但要注意,隱式聲名變數總是被建立為全域變數。看以下代碼,情願javascript語言強制聲明變數。建議大家一定要var聲明變數。 Java代碼
  1. <SCRIPT LANGUAGE="JavaScript">   
  2. function test();{   
  3.     var a=222;   
  4.  document.writeln(a);;   
  5. }   
  6. test();;   
  7. document.writeln(a);;   
  8. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">function test();{var a=222;document.writeln(a);;}test();;document.writeln(a);;</SCRIPT>
Java代碼
  1. <SCRIPT LANGUAGE="JavaScript">   
  2. function test();{   
  3.     a=222;   
  4.  document.writeln(a);;   
  5. }   
  6. test();;   
  7. document.writeln(a);;   
  8. </SCRIPT>   
<SCRIPT LANGUAGE="JavaScript">function test();{a=222;document.writeln(a);;}test();;document.writeln(a);;</SCRIPT> 

2、關於變數的範圍
猜猜以下代碼輸出什麼。 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. var x='000';   
  3. document.writeln(x);;   
  4. a();;   
  5. function a();{   
  6.     var x='aaa';   
  7.  function b();{   
  8.      document.writeln(x);;   
  9.         var x='bbb';   
  10.   document.writeln(x);;   
  11.  }   
  12.  b();;   
  13.     document.writeln(x);;   
  14. }   
  15. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">var x='000';document.writeln(x);;a();;function a();{var x='aaa';function b();{document.writeln(x);;var x='bbb';document.writeln(x);;}b();;document.writeln(x);;}</SCRIPT>

如果你的答案是   000 undefined bbb aaa。恭喜,ok.當代碼用到x變數時,先從函數塊(權威指南中用調用對象來解釋)中找,如果找不到,從上一級函數塊找,直到找到,如果知道頂層代碼(指var x='000';的位置)還沒找到定義,代碼會報未定義錯誤。

改一下代碼,得到 000 undefined 111 111 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. var x='000';   
  3. document.writeln(x);;   
  4. a();;   
  5. function a();{   
  6.  function b();{   
  7.      document.writeln(x);;   
  8.   document.writeln(x);;   
  9.  }   
  10.  document.writeln(x);;   
  11.  var x='111';   
  12.  b();;    
  13. }   
  14. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">var x='000';document.writeln(x);;a();;function a();{function b();{document.writeln(x);;document.writeln(x);;}document.writeln(x);;var x='111';b();;}</SCRIPT>

3、新的問題
變數個範圍清楚了,注意上面的代碼。為什麼我的function a()定義以前就可以調用a函數了,而我的var x='111';前“不可以用”x啊???
讓我把我的理解一一道來
首先:以下代碼讓我相信javascript有個先行編譯過程,不是完全按照順序解釋執行的。 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. a();;   
  3. function a();{   
  4.     alert();;   
  5. }   
  6. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">a();;function a();{alert();;}</SCRIPT>

 
個人理解這個先行編譯過程不會象java/c#那樣把代碼編譯成虛擬機器認識的語言,更不會象vb,vc那樣編譯成更底層的語言。猜想只是把這個函數預裝載到這段函數執行的全域環境中,在這個執行環境中,該函數被標識定義過,可以直接使用了。(看到網上很多人寫的AOP的javascript實現,其實這個先行編譯過程才是翻譯中繼資料最佳時候,可惜就javascript語言來講,是有些落伍了)

這個文章主要講變數的一些問題。變數說了,為什麼函數可以,我變數就不可以呢。 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. document.writeln(a);;   
  3. var a=0;   
  4. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">document.writeln(a);;var a=0;</SCRIPT>

為什麼我要輸出undefined呢?為什麼我a就不可以先行編譯一把呢?
大家看看以下兩段代碼會輸出什麼呢啊??? Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. document.writeln(a);;   
  3. a=0;   
  4. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">document.writeln(a);;a=0;</SCRIPT>
Java代碼
  1. <SCRIPT LANGUAGE="JavaScript">   
  2. document.writeln(a);;   
  3. </SCRIPT>   
<SCRIPT LANGUAGE="JavaScript">document.writeln(a);;</SCRIPT> 

可能你運行試了,可能你本來就知道,a未定義。哈哈哈,好了。
現在我確信var a=0;被javascript解譯器“先行編譯過”,至少是記錄下來了。甚至把它的值設定為 undefined。“undefined”這個詞名字取的很是讓人誤解,怎麼能叫未定義呢,分明是javascript中所有變數的初始化值。關於null與undefined的比較我實在不願提了。
注意上面兩段代碼還反映一個現象。隱式聲明的變數是在解釋的時候才把自己定義為全域變數的。

關於函數與變數javascript先行編譯的不同處理,大家可以與java class的載入過程比較下。java也是對基本類型設出值,對象為null的。(不往遠扯了)
4、區別未定義變數和未附值變數 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. var a;   
  3. document.writeln(a);;   
  4. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">var a;document.writeln(a);;</SCRIPT>
Java代碼
  1. <SCRIPT LANGUAGE="JavaScript">   
  2. document.writeln(a);;   
  3. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">document.writeln(a);;</SCRIPT>

未定義變數和未附值變數   權威指南中文版 定義的。通過第三條分析,我覺得變數就應該以   定義和未定義變數區別。未附值變數和undefined有點衝突,javascript不是強型別語言,沒發附預設值,才來了個undefined。
5、基本類型和參考型別
熟悉java的朋友可能這部分很清楚。沒啥
說頭。
6、javascript的記憶體回收
關於這部分內容一直沒見著個權威說法。在javascript權威指南中有兩小節提到這個問題。
對於字串、對象、資料這些沒有固定大小,必須為它們動態分配記憶體,但什麼時候回收這些記憶體呢?javascript使用和java一樣的garbage collection的方法。 Java代碼

  1. var s="hello";   
  2. var u=s.toUpperCase();;   
  3. s=u;  
var s="hello";var u=s.toUpperCase();;s=u;

運行這段代碼後,"hello"沒有變數會再用到他,這是"hello"的儲存空間的被記憶體回收了。對於javascript的記憶體回收,你唯一要關心的是,它一定會進行,不要對記憶體擔心。
注意,javascript不提供任何的強制記憶體回收或釋放記憶體的運算附或語句。
javascript的delete運算附和C++中的不同。 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. var o=new Object();;   
  3. o.name="zkj";   
  4. o.age=25;   
  5. o.bir=new Date();;   
  6. for(var key in o);{   
  7. document.writeln(key+':'+o[key]+'</br>');;   
  8. }   
  9. document.writeln('delete o.bir</br>');;   
  10. delete o.bir;   
  11. for(var key in o);{   
  12. document.writeln(key+':'+o[key]+'</br>');;   
  13. }   
  14. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">var o=new Object();;o.name="zkj";o.age=25;o.bir=new Date();;for(var key in o);{document.writeln(key+':'+o[key]+'</br>');;}document.writeln('delete o.bir</br>');;delete o.bir;for(var key in o);{document.writeln(key+':'+o[key]+'</br>');;}</SCRIPT>

7、作為屬性的變數
猜猜以下代碼會輸出什麼。 Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. var x=100;   
  3. document.writeln(x);;   
  4. add(x);;   
  5. document.writeln('</br>------------------------</br>');;   
  6. var x=200;   
  7. document.writeln(x);;   
  8. add(x);;   
  9. function add(x);{   
  10.     document.writeln(x);;    
  11.     var x=300;   
  12.     document.writeln(x);;    
  13.     var x=400;   
  14.     document.writeln(x);;   
  15. }   
  16. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">var x=100;document.writeln(x);;add(x);;document.writeln('</br>------------------------</br>');;var x=200;document.writeln(x);;add(x);;function add(x);{document.writeln(x);;var x=300;document.writeln(x);;var x=400;document.writeln(x);;}</SCRIPT>

估計很多人能得出正確答案
100 100 300 400
------------------------
200 200 300 400
但這裡我想引入  全域對象和調用對象的 概念(javascript權威指南是這麼翻譯滴) Java代碼

  1. <SCRIPT LANGUAGE="JavaScript">   
  2. var x=100;   //我們在全域對象中加了個屬性x. 對比   
  3.  //var o=new Object();;o.x=100;   
  4. document.writeln(this.x);;//用this訪問全域對象   
  5. add(this.x);;//把全域對象的屬性值傳遞對函數中   
  6. document.writeln('</br>------------------------</br>');;   
  7. this.x=200;//把全域變數中的x屬性修改掉   
  8. document.writeln(window.x);;   
  9. add(window.x);;   
  10. function add(x);{   
  11.     //假設有個局部對象,調用對象,函數調用過程中的對象   
  12. //  temp   temp.x=${傳入的值}   
  13.     document.writeln(x);; //哦這列印的可是參數中的值,也就是temp.x=this.x   
  14. //的值,   
  15.     var x=300;//把調用物件變數的簽名給覆蓋了.   
  16.     document.writeln(x);; //列印修改過的值。 temp.x   
  17.  var x=400;//temp.x=400   
  18.     document.writeln(x);;   
  19. }   
  20. </SCRIPT>  
<SCRIPT LANGUAGE="JavaScript">var x=100;   //我們在全域對象中加了個屬性x. 對比//var o=new Object();;o.x=100;document.writeln(this.x);;//用this訪問全域對象add(this.x);;//把全域對象的屬性值傳遞對函數中document.writeln('</br>------------------------</br>');;this.x=200;//把全域變數中的x屬性修改掉document.writeln(window.x);;add(window.x);;function add(x);{//假設有個局部對象,調用對象,函數調用過程中的對象//  temp   temp.x=${傳入的值}document.writeln(x);; //哦這列印的可是參數中的值,也就是temp.x=this.x//的值,var x=300;//把調用物件變數的簽名給覆蓋了.document.writeln(x);; //列印修改過的值。 temp.xvar x=400;//temp.x=400document.writeln(x);;}</SCRIPT>

在函數的調用過程中,假設有個調用對象存在,把函數的參數,和函數內的臨時變數當成這個調用對象的屬性。當然這個調用對象的生命週期很短。
注意,當我們訪問全域變數的屬性入x的時候,不必要用this.x 或window.x訪問,當在有<frame><iframe>的頁面時會出現混淆。
關於函數的詳細討論我後續會詳細討論。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.