零全零美(www.zzgwt.com)
          生活中的很多事情,并不像If...Else那么簡單!
          posts - 96,comments - 52,trackbacks - 0
              變量的生命周期又稱為作用域,是指某變量在程序中的有效范圍。根據(jù)作用域,變量可以分為全局變量和局部變量。
              1、  全局變量的作用域是全局性的,即在整個(gè)JavaScript程序中,全局變量處處都在。
              2、  而在函數(shù)內(nèi)部聲明的變量,只在函數(shù)內(nèi)部起作用。這些變量是局部變量,作用域是局部性的;函數(shù)的參數(shù)也是局部性的,只在函數(shù)內(nèi)部起作用。
              經(jīng)常見到網(wǎng)上有文章說:“在JavaScript中可以有兩種方式聲明全局變量:1、聲明變量時(shí)不使用var關(guān)鍵字 2、在函數(shù)外部聲明變量 使用第一種方法聲明變量時(shí),就算是在函數(shù)內(nèi)部,該變量仍為全局變量,使用第二種方法聲明變量時(shí),就算是用var關(guān)鍵字,那么聲明的變量也是全局變量,” 自己親手測試一下就知其中對錯(cuò):參看如下示例:

           1     <script type="text/javascript">
           2         var v01 = "我是全局變量v01"//使用var關(guān)鍵字聲明的全局變量
           3             v02 = "我是全局變量v02"//未使用var關(guān)鍵字聲明的全局變量
           4         function fun1(){
           5             alert(v01); //output "我是全局變量v01"
           6             alert(v02); //output "我是全局變量v02"
           7             
           8                 v03 = "我是全局變量v03";
           9             var v04 = "我是局部變量v04";
          10         }
          11         
          12         function fun2(){
          13             alert(v01); //output "我是全局變量v01"
          14             alert(v02); //output "我是全局變量v02"
          15              
          16             alert(v03); //error: "v03未定義" 
          17             alert(v04); //error:  "v04未定義"
          18             
          19         }
          20         
          21         fun2();
          22     </script>

            為什么結(jié)果與大家公認(rèn)的不一致呢,讓我們把程序做稍微的改動:
           
           1     <script type="text/javascript">
           2         var v01 = "我是全局變量v01"//使用var關(guān)鍵字聲明的全局變量
           3             v02 = "我是全局變量v02"//未使用var關(guān)鍵字聲明的全局變量
           4         function fun1(){
           5             alert(v01); //output "我是全局變量v01"
           6             alert(v02); //output "我是全局變量v02"
           7             
           8                 v03 = "我是全局變量v03";
           9             var v04 = "我是局部變量v04";
          10         }
          11         
          12         function fun2(){
          13             alert(v01); //output "我是全局變量v01"
          14             alert(v02); //output "我是全局變量v02"
          15              
          16             alert(v03); //output: "我是全局變量v03" 
          17             alert(v04); //error:  "v04未定義"
          18             
          19         }
          20         //兩個(gè)函數(shù)都調(diào)用
          21         fun1();
          22         fun2();
          23     </script>

          呵呵,這個(gè)時(shí)候,程序終于按照我們原先的設(shè)想執(zhí)行了,但是這個(gè)時(shí)候,我們就必須做下來好好總結(jié)一下了:
          如果我們在函數(shù)內(nèi)部聲明了一個(gè)全局變量,也就是聲明變量時(shí)未使用var關(guān)鍵字,當(dāng)我們在其他地方使用該變量時(shí),必須保證該函數(shù)已被調(diào)用,所以,如果真的要使用全局變量還是在函數(shù)外部聲明的好

          還有一個(gè)值得注意的地方就是:JavaScript變量作用范圍沒有語句塊的概念,他并不像JAVA一樣在for循環(huán)內(nèi)部聲明的變量,在for循環(huán)外部就不能使用,參看一下示例:
           1         function test(){
           2             for(var i =0 ; i <20; i++){
           3                 document.write(i+"<BR>");
           4                 if(i == 19) {
           5                     var j = "我是在for語句內(nèi)部聲明的";
           6                 }
           7             }
           8             alert(j); //output: "我是在for語句內(nèi)部聲明的"
           9         }
          10         test();

            除此之外,還有一個(gè)容易引起錯(cuò)誤的地方不能不說,參看一下程序:
          1         var strTest = "全局變量";
          2         function test1(){
          3             alert(strTest);  //output: "undefined"
          4             var strTest = "看看出錯(cuò)沒";
          5         }
          6         test1();
            先來解釋一下這個(gè)小程序,我們首先在函數(shù)外部聲明了一個(gè)全局性的變量,接著在函數(shù)內(nèi)部把它alert出來,最后我們又聲明了一個(gè)同全局變量的名字相同的一個(gè)局部變量,但是就是這個(gè)只有六行的小程序,其結(jié)果卻并不像我們想象的那樣輸出"看看出錯(cuò)沒",而是輸出了undefined,呵呵,看來“JavaScript真是處處是陷阱啊”!
            在網(wǎng)上GOOGLE了半天,找到了這樣一種說法:
             大家都知道JavaScript是一種解釋型的腳本語言,當(dāng)JavaScript運(yùn)行時(shí),首先查找所有的變量聲明,并以未定義的初始值創(chuàng)建變量。如果變量被聲明時(shí)有值,那么該變量仍以未定義的值初始化,并且只有在運(yùn)行了聲明行時(shí)才被聲明值取代。
            這也就解釋了以上的程序,其實(shí)如果我們在程序的第一行之前加上一句:alert(strTest);輸出結(jié)果依然會是undefined,看到這我想大家應(yīng)該也想到了,程序出錯(cuò)的原因并不是說聲明了一個(gè)與全局變量名稱相同的局部變量,而是只要在變量聲明語句之前調(diào)用該變量,該變量的值就一定是 undefined,但是如果我們調(diào)用一個(gè)沒有被聲明的變量,這個(gè)時(shí)候會報(bào)“變量未定義”的錯(cuò)誤,所以我們還必須得明白這兩者之間的區(qū)別,不過不管怎么說,一種好的編碼習(xí)慣還是避免把局部變量與全局變量聲明稱相同的名字!
            在看最后一種情況:注意以下程序:
           1         var strGloblVar = "我是全局變量";
           2         function father(){
           3             strFatherGloblVar = "在父函數(shù)中聲明的全局變量";
           4             var strFatherVar = "我是父函數(shù)中為局部變量,同時(shí)也是子函數(shù)中的全局變量";
           5             function child(){
           6                 strChildGloblVar = "在子函數(shù)中聲明的全局變量";
           7                 var strChildVar = "我是子函數(shù)中的局部變量";
           8                 alert(strFatherVar);  //output: "我是父函數(shù)中為局部變量,同時(shí)也是子函數(shù)中的全局變量"
           9                 alert(strChildVar);   //output: "我是子函數(shù)中的局部變量"
          10                 alert("子函數(shù)中:"+strGloblVar);   //output: "我是全局變量"
          11                 alert(strFatherGloblVar);
          12             }
          13             alert("父函數(shù)中:"+strGloblVar); //output: "我是全局變量"
          14             //alert(strChildVar); //error: strChildVar 未定義
          15             //alert(strChildGloblVar);  //error:strChildGloblVar 未定義
          16             return child();
          17         }
          18         
          19         father();
          20         alert("所有函數(shù)外部:"+strFatherGloblVar); //output: "所有函數(shù)外部:在父函數(shù)中聲明的全局變量"
          21         alert("所有函數(shù)的外部:"+strChildGloblVar); //output:"所有函數(shù)的外部:在子函數(shù)中聲明的全局變量"
             用過JavaScript閉包的人會很容易的看懂以上程序,閉包不是本文要說明的重點(diǎn),但是這個(gè)小例子可以幫我們證明在閉包的情況下,變量的生命周期并沒有因?yàn)槭褂瞄]包而有很大的改變,可以簡單的拋開閉包的概念,把father()函數(shù)內(nèi)部看成一個(gè)獨(dú)立的運(yùn)行環(huán)境。14行報(bào)錯(cuò),是因?yàn)閟trChildVar是child()函數(shù)中定義的局部變量,15行報(bào)錯(cuò),是因?yàn)樵谡{(diào)用strChildGloblVar之前child()函數(shù)未被執(zhí)行過,這和我們之前說的都一樣。但是當(dāng)我們在father()函數(shù)外部打印strFatherVar的時(shí)候會出現(xiàn)錯(cuò)誤,導(dǎo)致這種錯(cuò)誤的原因很簡單,strFatherVar雖然是child()的全局變量,但是卻是father()的局部變量。
          posted on 2008-06-27 17:04 零全零美 閱讀(3227) 評論(4)  編輯  收藏 所屬分類: JavaScript

          FeedBack:
          # re: JavaScript學(xué)習(xí)筆記(1)變量的生命周期
          2008-07-02 09:54 | eureka
          無所謂真正的“全局變量”。
          In top-level JavaScript code (i.e., code not contained within any function definitions), the scope chain consists of a single object, the global object. All variables are looked up in this object. If a variable does not exist, the variable value is undefined. In a (nonnested) function, however, the scope chain consists of two objects. The first is the function's call object, and the second is the global object. When the function refers to a variable, the call object (the local scope) is checked first, and the global object (the global scope) is checked second.
          摘自犀牛書 4.7節(jié)  回復(fù)  更多評論
            
          # re: JavaScript學(xué)習(xí)筆記(1)變量的生命周期
          2008-07-03 09:11 | 龐永慶
          你好 我是出版社的編輯,我看到你博客中的內(nèi)容,感覺寫的非常不錯(cuò),現(xiàn)在也正要出版一本JavaScript的書。如果想把JavaScript內(nèi)容和更多的人分享,可以和我聯(lián)系,把這些東西寫成書。
          我的郵箱:books_522008@yahoo.com.cn  回復(fù)  更多評論
            
          # re: JavaScript學(xué)習(xí)筆記(1)變量的生命周期
          2008-07-04 09:54 | 昨夜流星
          @eureka
          呵呵,學(xué)習(xí)中,談?wù)勛约旱挠^點(diǎn):
          JavaScript是一種解釋型的腳本語言,無法實(shí)現(xiàn)如JSP session 級別的變量更別說application級的了。
          也許我文中的說法不太嚴(yán)謹(jǐn)應(yīng)該指出:
          JavaScript中所謂的全局變量,其實(shí)只是page scope,而不是真正的application scope  回復(fù)  更多評論
            
          # re: JavaScript學(xué)習(xí)筆記(1)變量的生命周期
          2013-08-02 10:27 | fwd
          寫的很好  回復(fù)  更多評論
            
          主站蜘蛛池模板: 文化| 樟树市| 黑龙江省| 修水县| 姚安县| 卢龙县| 天气| 聂拉木县| 蓬安县| 宁阳县| 汾阳市| 尼玛县| 清镇市| 磐安县| 敖汉旗| 北海市| 溧水县| 玛沁县| 泰兴市| 嘉黎县| 高碑店市| 瑞金市| 南丹县| 手游| 札达县| 台北市| 慈溪市| 嘉定区| 海阳市| 桂林市| 西林县| 凌云县| 汉源县| 桃江县| 昌吉市| 宜川县| 张家界市| 榆社县| 柞水县| 天长市| 内丘县|