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

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

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

    BaSaRa 目前關心的是UI技術

    [引用] 對閉包的理解

    今天在群里面瞎談,就談到“閉包”上來了,何種語言支持閉包?自己g下吧,其中JavaScript是支持閉包概念的一種語言/腳本(?)。以下是我對他的見解(以javascript舉例)。

    先了解下在一個對象內如何聲明變量,一下以Test對象為例:
    Public變量:
    function Test()
    {
        
    this.x = 1;
    }
    或者
    Test.prototype.x = 1;
    公共變量簡而言之,外界對象可以對公共變量訪問,并且公共變量可以在對象的構造函數中聲明外,還可以在對象的prototype成員中聲明。換句話說,你可以在任何時候添加公共變量(利用prototype)。prototype是一個特別的成員變量,js就是利用這個成員變量的特性來實現繼承的。當一個成員被檢索且沒有在對象中發現的時候,那么它就會從對象構造器的prototype成員中獲取他。如果要從外界調用這個對象的方法,或者是通過這個方法操作這個對象里面的所有成員,你可以通過prototype加入:
    Test.prototype.Plus = function () {}

    Private變量:
    function Test()
    {
        
    var self = this;
        
        
    var x = 1;
        
        
    function Plus1() {}
        
        
    var pPlus = function Plus2() {}
    }
    私有的變量只能由成員的私有方法或者是特權方法(Privileged,下面講到)訪問,需要注意的是,上面的Plus1()這個方法和pPlus()這個方法是一樣的,只是聲明的方式不通而已,他們都是私有方法,他和特權變量的聲明方法很相似,只是少了個this多了個var,但是他們是不同的,應該特別注意。另外一點是,私有變量是在無法被外界訪問的同時,他也不能由對象的公共方法訪問。私有方法只是在構造函數內的內部方法。私有變量只能在構造函數中聲明。

    Privileged變量:
    function Test()
    {
        
    this.pPlus = function () {}
    }
    什么叫Privileged(特權)變量呢?特權方法可以訪問私有方法和私有變量,同時他對外界是可見的。你可以重新聲明這個私有方法或者是刪除他(重新對這個特權方法賦值,null值表示刪除),但是不能改變他。特權變量也只能在構造函數中聲明。

    好了,對象聲明介紹到這里,這些聲明模式都是由js的closure(閉包)特性所支持的,下面介紹閉包。

    在一個閉包內,你可以暫且(?)理解成在構造函數內,內部函數總是可以訪問函數外部的變量和參數的。就算在內部函數return后,閉包內的所有變量都會被保存起來,就好像一個上下文一樣。下面我以一個例子說明這個問題,例子來源在群內,由YOK提供(例子已經被修改,只是用來簡單說明問題)。

    說明:按test按鈕輸出相加的值,期望值為3。
    <html>
        
    <body>
            
    <input type="button" id="test" value="test" />
            
    <script>
    function Test (x, y)
    {
        
    var x = x;
        
    var y = y;
    }
    Test.prototype.add 
    = function ()
    {
        alert(
    this.x + this.y);
    }

    var t = new Test(12);
    document.getElementById('test').onclick 
    = t.add;
            
    </script>
        
    </body>
    </html>

    運行例子,但是輸出"NaN"。這是什么問題呢,我最初調試的時候,以為是this的問題,我原本理解成在add方法中this是指向test按鈕(其實this指向window對象),而他不包含x和y的兩個變量,所以輸出錯誤。首先,這個理解是正確的,但是你要如何修改才能獲取正確的結果呢。我們已經知道,在Test構造函數中,我們聲明的x,y是兩個私有變量,你不可能在外部訪問到,所以必須另覓他路。我們利用特權變量來解決。
    <html>
        
    <body>
            
    <input type="button" id="test" value="test" NAME="test"/>
            
    <script>
    function Test (x, y)
    {
        
    var x = x;
        
    var y = y;
        
        
    this.add = function ()    // 特權變量,可以訪問私有變量,又對外公開
        {
            alert(x 
    + y);
        }
    }

    var t = new Test(12);
    document.getElementById('test').onclick 
    = t.add;
            
    </script>
        
    </body>
    </html>

    上面呈現的是閉包的其中一個特性,下面用來說他的另外一個特性。
    <html>
        
    <body>
            
    <input type="button" id="test" value="test" NAME="test"/>
            
    <script>
    function Test ()
    {
        
    var z = 1;
        
        
    this.add = function ()
        {
            alert(z
    ++);
        }
    }

    var t = new Test();
    document.getElementById('test').onclick 
    = t.add;
            
    </script>
        
    </body>
    </html>
    每次輸出,值都會增加1,說明閉包內上下文就算add方法return后都會被保存。

    最后說下怎么動態替換行為(這里是按鈕click的行為)。
    <html>
        
    <body>
            
    <input type="button" id="test" value="test" NAME="test"/>
            
    <script>
    function Test ()
    {
        
    var z = 1;
        
    var self = this;
        
    var pBtn = null;
        
        
    this.selfSubtract = function ()
        {
            z
    --;z--;
            alert(z);
            pBtn.onclick 
    = self.selfPlus;
        }
        
        
    this.selfPlus = function ()
        {
            z
    ++;
            alert(z);
            pBtn.onclick 
    = self.selfSubtract;
        }
        
        
    this.getFunction = function (btn)
        {
            pBtn 
    = btn;
            
    return self.selfSubtract;
        }
    }

    var t = new Test();
    var btn = document.getElementById('test');
    btn.onclick 
    = t.getFunction(btn);
            
    </script>
        
    </body>
    </html>
    以上是我對他的一點見解,closure是js的一個特性而已,我們可以利用這個特性使設計更靈活,其他語言,我google到的好像叫Lua,不知道他是什么,他也支持。由于對js了解不深,請高手斧正確,enjoy it~~~ :)

    posted on 2006-06-13 11:13 BaSaRa 閱讀(298) 評論(0)  編輯  收藏 所屬分類: Javascript

    My Links

    Blog Stats

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲人和日本人jizz| 亚洲欧洲久久久精品| 亚洲视频在线免费看| 花蝴蝶免费视频在线观看高清版| 免费一级毛片在线播放不收费| 亚洲另类无码一区二区三区| 久久精品免费一区二区喷潮| 亚洲18在线天美| 最近2019中文字幕mv免费看 | 亚洲人JIZZ日本人| 国产99久久久久久免费看| 国产亚洲精品不卡在线| 免费人成黄页在线观看日本| 亚洲国产精品久久久久婷婷老年| 国产性爱在线观看亚洲黄色一级片| caoporn国产精品免费| 亚洲精品美女久久久久99| 激情五月亚洲色图| 国产高清免费观看| 韩国免费A级毛片久久| 亚洲综合一区二区国产精品| 91精品免费国产高清在线| 亚洲精品宾馆在线精品酒店| 亚洲国产成人乱码精品女人久久久不卡| 精品久久久久久无码免费| 处破痛哭A√18成年片免费| 免费观看亚洲人成网站| 中文字幕无码视频手机免费看 | 国产亚洲综合视频| 亚洲日韩精品无码专区网址| 91免费人成网站在线观看18| 亚洲毛片网址在线观看中文字幕 | 免费观看国产网址你懂的| 亚洲中文无码卡通动漫野外| 亚洲v国产v天堂a无码久久| 久久精品国产大片免费观看| 亚洲色欲色欱wwW在线| 亚洲综合精品香蕉久久网| 99久久99这里只有免费费精品| 国产av无码专区亚洲av毛片搜| 亚洲AV综合色区无码另类小说|