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

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

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

    The NoteBook of EricKong

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

     

    jQuery片段:

     

    1(function(){  
    2 //這里忽略jQuery所有實(shí)現(xiàn)  
    3 }
    )()

     

      半年前初次接觸jQuery的時(shí)候,我也像其他人一樣很興奮地想看看源碼是什么樣的。然而,在看到源碼的第一眼,我就迷糊了。為什么只有一個(gè)匿名函數(shù)又沒看到運(yùn)行(當(dāng)然是運(yùn)行了……),就能有jQuery這么個(gè)函數(shù)庫(kù)了?于是,我抱著疑問來到CSDN。結(jié)果相信現(xiàn)在很多人都很清楚了(因?yàn)樵谖抑笠膊环碚撸呛莮)。當(dāng)一個(gè)匿名函數(shù)被括起來,然后再在后面加一個(gè)括號(hào),這個(gè)匿名函數(shù)就能立即運(yùn)行起來!真神奇哦!

      嘿嘿!胡鬧到此為止。在這一節(jié),我們碰到的jQuery片段是一組立即運(yùn)行的匿名函數(shù)。而這種用法在論壇上也曾引起過激辯——這段代碼究竟屬不屬于閉包呢?帶著這個(gè)疑問,我們從基礎(chǔ)開始,分析每個(gè)關(guān)鍵要素,尋找屬于自己的答案。(沒錯(cuò),自己的答案!在我看來,所有理論只是形式,只要它有利于我們的應(yīng)用實(shí)現(xiàn),就是可取的——黑貓白貓,抓到老鼠的就是好貓!)

      要說匿名函數(shù),我們首先要由函數(shù)本身說起。函數(shù)的定義如下:

        函數(shù)是將唯一的輸出值賦予給每一輸入的“法則”。

      當(dāng)然,這只是數(shù)學(xué)上的定義。但是,在計(jì)算機(jī)編程語言中,函數(shù)的定義也八九不離十。因?yàn)椋覀兌贾溃?jì)算機(jī)中的函數(shù),也類似數(shù)學(xué)定義中的描述,它是將輸入的若干數(shù)據(jù),經(jīng)過代碼設(shè)定的邏輯操作處理后,返回唯一的輸出的一組代碼組合塊。——當(dāng)然,特例是,輸入的數(shù)據(jù)為空或輸出的數(shù)據(jù)為空,或者兩者都為空。

      下面,我們先初步了解一下和匿名函數(shù)相關(guān)的概念。

        * 函數(shù)聲明(function 語句)

      要使用一個(gè)函數(shù),我們就得首先聲明它的存在。而我們最常用的方式就是使用function語句來定義一個(gè)函數(shù),如:

    1 function abc(){ // code to process }

       當(dāng)然,你的函數(shù)也可以是帶參數(shù)的,甚至是帶返回值的。


    1 function abc(x,y){ return x+y; }


      但是,無論你怎么去定義你的函數(shù),JS解釋器都會(huì)把它翻譯成一個(gè)Function對(duì)象。例如,你在定義上面的其中一個(gè)例子的函數(shù)號(hào),再輸入如下代碼:


    1 alert(typeof abc);// "function"

      你的瀏覽器就會(huì)彈出提示框,提示你abc是一個(gè)Function對(duì)象。那么Function對(duì)象究竟是什么呢?

        * Function 對(duì)象

      Function對(duì)象是JavaScript里面的固有對(duì)象,所有的函數(shù)實(shí)際上都是一個(gè)Function對(duì)象。關(guān)于這個(gè)方面的討論,我們留到下一個(gè)專題節(jié)。我們先看看,Function對(duì)象能不能直接運(yùn)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新的函數(shù)呢?答案是肯定的。例如:


    1 var abc = new Function("x","y","return x*y;"); alert(abc(2,3)); // "6"

      相信大家現(xiàn)在對(duì)如何聲明一個(gè)函數(shù)應(yīng)該是有所了解了。那么什么才是匿名函數(shù)呢?

        * 聲明匿名函數(shù)

      顧名思義,匿名函數(shù)就是沒有實(shí)際名字的函數(shù)。例如,我們把上面的例子中,函數(shù)的名字去掉,再判斷一下他是不是一個(gè)函數(shù):

     

    1    alert(typeof function(){});// "function" 
    2    alert(typeof function(x,y){return x+y;});// "function" 
    3    alert(typeof new Function("x","y","return x*y;"))// "function" 

     

      我們可以很容易地看到,它們?nèi)际荈unction對(duì)象,換言之,他們都是函數(shù),但是他們都有一個(gè)特點(diǎn)——沒有名字。所以我們把他們稱作“匿名函數(shù)”。然而,正因?yàn)樗麄儧]有“名字”,我們也沒有辦法找到他們。這就引申了如何去調(diào)用一個(gè)匿名函數(shù)的問題了。

        * 匿名函數(shù)的調(diào)用

      要調(diào)用一個(gè)函數(shù),我們必須要有方法定位它,引用它。所以,我們會(huì)需要幫它找一個(gè)名字。例如:


    1 var abc=function(x,y){ return x+y; } alert(abc(2,3)); // "5"

      上面的操作其實(shí)就等于換個(gè)方式去定義函數(shù),這種用法是我們比較頻繁遇到的。例如我們?cè)谠O(shè)定一個(gè)DOM元素事件處理函數(shù)的時(shí)候,我們通常都不會(huì)為他們定名字,而是賦予它的對(duì)應(yīng)事件引用一個(gè)匿名函數(shù)。

      對(duì)匿名函數(shù)的調(diào)用其實(shí)還有一種做法,也就是我們看到的jQuery片段——使用()將匿名函數(shù)括起來,然后后面再加一對(duì)小括號(hào)(包含參數(shù)列表)。我們?cè)倏匆幌乱韵吕樱?/p>

    alert((function(x,y){return x+y;})(2,3));// "5" 
    alert((new Function("x","y","return x*y;"))(2,3));// "6" 

      很多人或許會(huì)奇怪,為什么這種方法能成功調(diào)用呢?覺得這個(gè)應(yīng)用奇怪的人就看一下我以下這段解釋吧。

      大家知道小括號(hào)的作用嗎?小括號(hào)能把我們的表達(dá)式組合分塊,并且每一塊,也就是每一對(duì)小括號(hào),都有一個(gè)返回值。這個(gè)返回值實(shí)際上也就是小括號(hào)中表達(dá)式的返回值。所以,當(dāng)我們用一對(duì)小括號(hào)把匿名函數(shù)括起來的時(shí)候,實(shí)際上小括號(hào)對(duì)返回的,就是一個(gè)匿名函數(shù)的Function對(duì)象。因此,小括號(hào)對(duì)加上匿名函數(shù)就如同有名字的函數(shù)般被我們?nèi)〉盟囊梦恢昧恕K匀绻谶@個(gè)引用變量后面再加上參數(shù)列表,就會(huì)實(shí)現(xiàn)普通函數(shù)的調(diào)用形式。

      不知道以上的文字表述大家能不能看明白,如果還是理解不了的話,再看一下以下的代碼試試吧。


    1  var abc=function(x,y){return x+y;};// 把匿名函數(shù)對(duì)象賦給abc 
    2  // abc的constructor就和匿名函數(shù)的 constructor一樣了。也就是說,兩個(gè)函數(shù)的實(shí)現(xiàn)是一樣的。 
    3  alert((abc).constructor==(function(x,y){return x+y;}).constructor); 

      PS:constructor是指創(chuàng)建對(duì)象的函數(shù)。也就是函數(shù)對(duì)象所代表的函數(shù)體。

      總之,將其(被小括號(hào)包含的匿名函數(shù))理解為括號(hào)表達(dá)式返回的函數(shù)對(duì)象,然后就可以對(duì)這個(gè)函數(shù)對(duì)象作正常的參數(shù)列表調(diào)用了。(前面這里犯了個(gè)錯(cuò)誤,只有函數(shù)表達(dá)式還是不能直接調(diào)用函數(shù)的,去掉匿名函數(shù)括號(hào)必須要伴隨將表達(dá)式賦值。也就是(function(){alert(1)})()應(yīng)該是與 a=function(){alert(1)}()等價(jià),不能連a=都去掉。)

        * 閉包

       閉包是什么?閉包是指某種程序語言中的代碼塊允許一級(jí)函數(shù)存在并且在一級(jí)函數(shù)中所定義的自由變量能不被釋放,直到一級(jí)函數(shù)被釋放前,一級(jí)函數(shù)外也能應(yīng)用這些未釋放的自由變量。

      怎樣?看得一頭冒汗吧……沒事,我也是(雖然是我是了解的,只是表達(dá)能力的問題)。讓我們換個(gè)更加簡(jiǎn)單的方法說明:閉包,其實(shí)是一種語言特性,它是指的是程序設(shè)計(jì)語言中,允許將函數(shù)看作對(duì)象,然后能像在對(duì)象中的操作搬在函數(shù)中定義實(shí)例(局部)變量,而這些變量能在函數(shù)中保存到函數(shù)的實(shí)例對(duì)象銷毀為止,其它代碼塊能通過某種方式獲取這些實(shí)例(局部)變量的值并進(jìn)行應(yīng)用擴(kuò)展。

      不知道這么再解釋后會(huì)否更加清晰,如果還是不明白,那么我們?cè)俸?jiǎn)化一下:閉包,其實(shí)就是指程序語言中能讓代碼調(diào)用已運(yùn)行的函數(shù)中所定義的局部變量。

      現(xiàn)在我們看一個(gè)例子:


     



       
    var abc=function(y){ 
       
    var x=y;// 這個(gè)是局部變量 
       return function(){ 
          alert(x
    ++);// 就是這里調(diào)用了閉包特性中的一級(jí)函數(shù)局部變量的x,并對(duì)它進(jìn)行操作 
          alert(y--);// 引用的參數(shù)變量也是自由變量 
        }
    }(
    5);// 初始化 
       abc();// "5" "5" 
       abc();// "6" "4" 
       abc();// "7" "3" 
       alert(x);// 報(bào)錯(cuò)!“x”未定義! 

      看到這里,你能判斷究竟jQuery的那個(gè)代碼片段是否閉包了嗎?

      以我的理解來說吧。是否應(yīng)用了閉包特性,必須確定該段代碼有沒有最重要的要素:未銷毀的局部變量。那么很顯然,沒有任何實(shí)現(xiàn)的匿名函數(shù)不可能應(yīng)用了閉包特性。但如果匿名函數(shù)里面有實(shí)現(xiàn)呢?那也還得確定它的實(shí)現(xiàn)中有沒有用到那些未銷毀的局部變量。所以如果問你那個(gè)開篇中的jQuery代碼片段是應(yīng)用了JS里的什么特性?那么它只是匿名函數(shù)與匿名函數(shù)的調(diào)用而已。但是,它隱含了閉包的特性,并且隨時(shí)可以實(shí)現(xiàn)閉包應(yīng)用。因?yàn)镴S天生就是有這個(gè)特性的!(這只是我的理解,我也想知道你的理解,歡迎交流!關(guān)于閉包,有機(jī)會(huì)還是獨(dú)立再開一個(gè)專題吧!)

    posted on 2010-05-18 09:15 Eric_jiang 閱讀(528) 評(píng)論(0)  編輯  收藏 所屬分類: JavaScript
    主站蜘蛛池模板: 国产亚洲人成在线影院| 亚洲AV综合色区无码一区爱AV| 最近的中文字幕大全免费版| 在线a免费观看最新网站| 久久精品国产这里是免费| 永久免费A∨片在线观看| 花蝴蝶免费视频在线观看高清版| 精品免费久久久久国产一区 | 亚洲AV无码精品色午夜在线观看| 亚洲中文字幕无码一区二区三区 | 毛片基地免费观看| 成人免费a级毛片| 毛片a级毛片免费播放100| 成年人视频在线观看免费| 成人性生交视频免费观看| 日本一道一区二区免费看| 免费成人av电影| 亚洲欧洲日产国码高潮αv| 综合亚洲伊人午夜网 | 精品亚洲国产成AV人片传媒| 亚洲美女aⅴ久久久91| 亚洲天堂电影在线观看| 亚洲国产成人久久精品软件| 精品亚洲成a人在线观看| 草久免费在线观看网站| 三级网站免费观看| 67pao强力打造高清免费| 91免费精品国自产拍在线不卡| 成人免费a级毛片无码网站入口 | 免费无码中文字幕A级毛片| 亚欧在线精品免费观看一区| 蜜桃视频在线观看免费网址入口| 国产免费AV片无码永久免费| 国产国拍精品亚洲AV片| 91亚洲国产成人久久精品网站| 中中文字幕亚洲无线码| 黄页网址在线免费观看| 免费黄网站在线看| 国产三级在线观看免费| 中文字幕亚洲天堂| 亚洲黄色免费网站|