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

    隨筆分類

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 色偷偷亚洲女人天堂观看欧| 亚洲熟妇av一区二区三区 | 无遮挡国产高潮视频免费观看| 一个人在线观看视频免费| 亚洲精品视频观看| ww4545四虎永久免费地址| 亚洲欧洲视频在线观看| 麻豆国产精品免费视频| 2020天堂在线亚洲精品专区| 97人伦色伦成人免费视频| 亚洲色大网站WWW永久网站| 免费无码又爽又刺激高潮的视频| 中文字幕av无码不卡免费| 精品国产亚洲一区二区在线观看 | 亚洲日产2021三区在线| 99久久这里只精品国产免费| 亚洲人成免费电影| 日韩毛片免费在线观看| 一级做a爱过程免费视频高清 | 四虎永久在线精品免费观看地址| 青青青亚洲精品国产| 在线观看亚洲精品国产| 国产免费无码AV片在线观看不卡 | 亚洲不卡中文字幕无码| 4444www免费看| 日韩亚洲产在线观看| 亚洲成a人片在线观看国产| 久久九九免费高清视频 | 亚洲人成网亚洲欧洲无码| 国产亚洲福利一区二区免费看| 思思久久99热免费精品6| 亚洲第一AAAAA片| 免费做爰猛烈吃奶摸视频在线观看 | 在线观看免费视频一区| 91亚洲国产成人久久精品| 国产国产人免费视频成69大陆| 国产永久免费高清在线| 亚洲精品亚洲人成在线播放| 亚洲国产精品无码久久青草 | 免费看一级一级人妻片| 成人免费无码大片a毛片|