<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    當(dāng)柳上原的風(fēng)吹向天際的時(shí)候...

    真正的快樂(lè)來(lái)源于創(chuàng)造

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
    閉包是JavaScript的復(fù)雜特性之一,搞清楚它有益于JS復(fù)雜程序的編寫和排錯(cuò)。什么是閉包呢?讓我們先看看《jQuery基礎(chǔ)教程》一書中對(duì)閉包的描述:

    “當(dāng)內(nèi)部函數(shù)在定義它的作用于的外部被引用時(shí),就創(chuàng)建了該內(nèi)部函數(shù)的一個(gè)閉包。在這種情況下,我們稱布什內(nèi)部函數(shù)局部變量的變量為自由變量,稱外部函數(shù)的調(diào)用環(huán)境為封閉閉包的環(huán)境。從本質(zhì)上講,如果內(nèi)部函數(shù)引用了位于外部函數(shù)中的變量,相當(dāng)于授權(quán)該變量能夠被延遲使用。因此,當(dāng)外部函數(shù)調(diào)用完成后,這些變量的內(nèi)存不會(huì)被釋放,因?yàn)殚]包仍然需要使用它們。”

    這段話解釋得很清楚了。如果再簡(jiǎn)短一些,用我自己的話說(shuō),閉包=封閉+打包,它的作用是將內(nèi)部函數(shù)及其使用到的外部變量(內(nèi)部函數(shù)的作用環(huán)境)封閉在一起打包使用。具體過(guò)程請(qǐng)看下面的程序:
    <SCRIPT LANGUAGE="JavaScript">
    <!--
        
    // 定義兩個(gè)引用
        var pointer1;
        
    var pointer2;

        
    // 外部函數(shù)定義
        function outer(){
            
    // 外部函數(shù)的局部變量
            var i=0;

            
    // 在外部函數(shù)內(nèi)部定義的內(nèi)部函數(shù),使用了外部函數(shù)的局部變量i
            function inner(){
                alert(i);
                i
    ++;
            }

            
    // 將兩個(gè)引用指向內(nèi)部函數(shù)inner
            pointer1=inner;
            pointer2
    =inner;
        }

        outer();
        alert(
    "通過(guò)引用調(diào)用內(nèi)部函數(shù)開始");
        pointer1();
    // 彈出0
        pointer1();// 彈出1
        pointer2();// 彈出2
        pointer2();// 彈出3

        
    //-->
    </SCRIPT>

    執(zhí)行以上程序,很容易就發(fā)覺(jué),內(nèi)部函數(shù)inner和外部函數(shù)定義的局部變量i被封閉并打包在一起了,就是閉包。這種方式和Java中向匿名類傳遞參數(shù)需要用final指定外部變量的做法異曲同工,都是改變局部變量的生存周期和作用范圍以配合特定函數(shù)的使用而已,不同的是Java在明JS在暗。

    如果創(chuàng)建了內(nèi)部函數(shù)的多個(gè)副本,那么被打包的外部函數(shù)中的變量也會(huì)產(chǎn)生互不影響的多個(gè)副本,從下面的程序可以清晰的看出來(lái):
    <SCRIPT LANGUAGE="JavaScript">
    <!--
        
    // 定義兩個(gè)引用
        var pointer1;
        
    var pointer2;

        
    // 外部函數(shù)定義
        function outer(){
            
    // 外部函數(shù)的局部變量
            var i=0;

            
    // 在外部函數(shù)內(nèi)部定義的內(nèi)部函數(shù),使用了外部函數(shù)的局部變量i
            function inner(){
                alert(i);
                i
    ++;
            }

            
    // 返回內(nèi)部函數(shù)的引用
            return inner;
        }

        
    // 將引用指向內(nèi)部函數(shù)
        pointer1=outer();
        pointer2
    =outer();

        alert(
    "通過(guò)引用調(diào)用內(nèi)部函數(shù)開始");

        pointer1();
    // 彈出0
        pointer1();// 彈出1

        pointer2();
    // 彈出0
        pointer2();// 彈出1

        
    //-->
    </SCRIPT>

    明顯,pointe1和pointer2指向的是inner的兩個(gè)副本,它們各自有不同的閉包環(huán)境,因此使用到的i也是從屬于各自閉包環(huán)境的兩個(gè)不同變量,它們地址,值都各不相同,相同的只有名字而已,就好像兩個(gè)一般函數(shù)中都有變量i一樣。

    以上程序的完整代碼請(qǐng)見:http://m.tkk7.com/Files/heyang/closure20090823214249.rar

    JS閉包的這個(gè)特性對(duì)動(dòng)態(tài)創(chuàng)建的程序特別有效,如下圖中“刪除”按鈕的創(chuàng)建,就會(huì)用到閉包。


    請(qǐng)看代碼:
        // deleteImgCell
        var deleteBtn=document.createElement("input");
        deleteBtn.setAttribute(
    "type","button");
        deleteBtn.setAttribute(
    "value","刪除");
        deleteBtn.onclick
    =function(){deleteRow(code);};// 這里用到了閉包
        
    var deleteBtnCell=document.createElement("td");
        deleteBtnCell.appendChild(deleteBtn);

    deleteBtn.onclick=function(){deleteRow(code);};這句代碼為什么一定要用一個(gè)函數(shù)體包容一下呢?我們知道deleteRow這個(gè)函數(shù)的作用是刪除掉一個(gè)表格行,傳入的參數(shù)是行的id,而每行的id是不同的,程序中的id值來(lái)自于局部變量code,我們不希望它創(chuàng)建完按鈕后值發(fā)生變化而是希望它運(yùn)行時(shí)的值和每個(gè)按鈕的點(diǎn)擊相應(yīng)函數(shù)綁定在一起,用JS的閉包正好完成了這一點(diǎn)。

    以上代碼的完整程序請(qǐng)見:http://m.tkk7.com/Files/heyang/StockTable.rar

    http://m.tkk7.com/heyang/archive/2009/08/21/292106.html 中的程序里也使用到了閉包,以下的程序:
        window.onload=function(){

            
    var menubar=$("menubar");

            
    for(var i=0;i<menubar.childNodes.length;i++){
                
    new function(){// 這里使用了閉包,將局部變量和事件響應(yīng)函數(shù)打包封閉在了一起.
                    
    var li=menubar.childNodes[i];
                    
    var subul=li.childNodes[2];

                    li.attachEvent('onmouseover',
                        
    function(){
                            subul.style.display
    ="block";
                        }
                    );
                    li.attachEvent('onmouseout',
                        
    function(){
                            subul.style.display
    ="none";
                        }
                    );
                }
            }
        }

    當(dāng)然,不要紅字部分的function也是一種閉包,只是打包封閉的環(huán)境錯(cuò)誤了而已.

    以上代碼的完整程序請(qǐng)見:http://m.tkk7.com/Files/heyang/JSCSSPopupmenu20090821151741.rar


    posted on 2009-08-23 21:24 何楊 閱讀(945) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费观看的毛片大全| 亚洲国产高清视频在线观看| 最近最新中文字幕完整版免费高清 | 亚洲人成777在线播放| 中文字幕亚洲不卡在线亚瑟| 九九九精品成人免费视频| 久久99精品视免费看| 成在人线av无码免费高潮水 | 欧洲精品成人免费视频在线观看 | 精品亚洲视频在线观看| 国产片免费福利片永久| 影音先锋在线免费观看| 成年黄网站色大免费全看| 午夜私人影院免费体验区| 美丽姑娘免费观看在线观看中文版| 一级做受视频免费是看美女| 日韩国产欧美亚洲v片| 亚洲熟妇无码八V在线播放| 亚洲日韩乱码久久久久久| 99亚洲精品高清一二区| 亚洲国产精品无码成人片久久| 亚洲天堂中文字幕在线| 亚洲乱码中文字幕手机在线 | 亚洲av中文无码乱人伦在线观看| 亚洲一区二区三区国产精品无码| 亚洲美女aⅴ久久久91| 亚洲2022国产成人精品无码区| 亚洲av伊人久久综合密臀性色| 中文字幕亚洲综合久久菠萝蜜| 亚洲精品国产精品国自产观看 | 国产成人亚洲精品91专区高清 | 日韩免费高清一级毛片在线| 在线观看日本免费a∨视频| 青青草a免费线观a| 日韩av无码成人无码免费| 大地资源在线观看免费高清| 最近高清国语中文在线观看免费| 午夜爱爱免费视频| 国产公开免费人成视频 | 中文字幕永久免费| 中文字幕成人免费高清在线|