欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript 匿名函數(shù)的理解(透徹版)

 更新時間:2010年01月28日 23:04:04   作者:  
網(wǎng)上很多解釋,我無法理解,我想知道原理。。。這篇文章應該可以透徹一點
復制代碼 代碼如下:

(function(){
//這里忽略jQuery所有實現(xiàn)
})();
(function(){ //這里忽略jQuery所有實現(xiàn) })();

  半年前初次接觸jQuery的時候,我也像其他人一樣很興奮地想看看源碼是什么樣的。然而,在看到源碼的第一眼,我就迷糊了。為什么只有一個匿 名函數(shù)又沒看到運行(當然是運行了……),就能有jQuery這么個函數(shù)庫了?于是,我抱著疑問來到CSDN。結果相信現(xiàn)在很多人都很清楚了(因為在我之 后也不乏來者,呵呵~)。當一個匿名函數(shù)被括起來,然后再在后面加一個括號,這個匿名函數(shù)就能立即運行起來!真神奇哦!

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

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

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

  當然,這只是數(shù)學上的定義。但是,在計算機編程語言中,函數(shù)的定義也八九不離十。因為,我們都知道,計算機中的函數(shù),也類似數(shù)學定義中的描述,它是將輸入的若干數(shù)據(jù),經(jīng)過代碼設定的邏輯操作處理后,返回唯一的輸出的一組代碼組合塊?!斎?,特例是,輸入的數(shù)據(jù)為空或輸出的數(shù)據(jù)為空,或者兩者都為空。

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

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

復制代碼 代碼如下:

function abc(){
// code to process
}
function abc(){ // code to process }
  當然,你的函數(shù)也可以是帶參數(shù)的,甚至是帶返回值的。

view plaincopy to clipboardprint?
function abc(x,y){
return x+y;
}
function abc(x,y){ return x+y; }

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

alert(typeof abc);// "function"
  你的瀏覽器就會彈出提示框,提示你abc是一個Function對象。那么Function對象究竟是什么呢?

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

復制代碼 代碼如下:

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

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

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

復制代碼 代碼如下:

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

  我們可以很容易地看到,它們全都是Function對象,換言之,他們都是函數(shù),但是他們都有一個特點——沒有名字。所以我們把他們稱作“匿名函數(shù)”。然而,正因為他們沒有“名字”,我們也沒有辦法找到他們。這就引申了如何去調用一個匿名函數(shù)的問題了。

匿名函數(shù)的調用
  要調用一個函數(shù),我們必須要有方法定位它,引用它。所以,我們會需要幫它找一個名字。例如:
復制代碼 代碼如下:

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

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

  對匿名函數(shù)的調用其實還有一種做法,也就是我們看到的jQuery片段——使用()將匿名函數(shù)括起來,然后后面再加一對小括號(包含參數(shù)列表)。我們再看一下以下例子:

復制代碼 代碼如下:

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

  很多人或許會奇怪,為什么這種方法能成功調用呢?覺得這個應用奇怪的人就看一下我以下這段解釋吧。

  大家知道小括號的作用嗎?小括號能把我們的表達式組合分塊,并且每一塊,也就是每一對小括號,都有一個返回值。這個返回值實際上也就是小括號中表達式的返回值。所以,當我們用一對小括號把匿名函數(shù)括起來的時候,實際上小括號對返回的,就是一個匿名函數(shù)的Function對象。因此,小括號對加上匿名函數(shù)就如同有名字的函數(shù)般被我們取得它的引用位置了。所以如果在這個引用變量后面再加上參數(shù)列表,就會實現(xiàn)普通函數(shù)的調用形式。

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

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

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

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

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

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

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

  現(xiàn)在我們看一個例子:
復制代碼 代碼如下:

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

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

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

相關文章

  • javascript函數(shù)定義的幾種區(qū)別小結

    javascript函數(shù)定義的幾種區(qū)別小結

    本篇文章主要是對javascript函數(shù)定義的幾種區(qū)別進行了詳細的總結介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • js獲取html頁面節(jié)點方法(遞歸方式)

    js獲取html頁面節(jié)點方法(遞歸方式)

    這篇文章主要介紹了js使用遞歸方式獲取html頁面節(jié)點的方法,大家可以參考使用吧
    2013-12-12
  • avalonjs制作響應式瀑布流特效

    avalonjs制作響應式瀑布流特效

    瀑布流主要應用在圖片展示頁面上。如果有一大批圖片需要展示,原始圖片尺寸不一致,又希望每張圖片都能不剪裁,完整顯示,那么就要給圖片規(guī)定一個寬度,解放它們的高度。利用網(wǎng)頁高度不限這個特性,充分利用頁面的空間,盡可能的展示多的圖片。下面我們就來詳細探討下
    2015-05-05
  • fckeditor粘貼Word時彈出窗口取消的方法

    fckeditor粘貼Word時彈出窗口取消的方法

    這篇文章主要介紹了fckeditor粘貼Word時彈出窗口取消的方法,是應用fckeditor時非常實用的技巧,需要的朋友可以參考下
    2014-10-10
  • 10 種最常見的 Javascript 錯誤(頻率最高)

    10 種最常見的 Javascript 錯誤(頻率最高)

    本文是小編給大家收藏的JavaScript 中頻度最高的 10 種錯誤,我們會告訴你什么原因導致了這些錯誤,以及如何防止這些錯誤發(fā)生。需要的朋友參考下
    2018-02-02
  • JS字符串截取出現(xiàn)的bug以及解決方式

    JS字符串截取出現(xiàn)的bug以及解決方式

    之前在獲取元素屬性時,踩了個坑,記錄一下,下面這篇文章主要給大家介紹了關于JS字符串截取出現(xiàn)的bug以及解決方式,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • DWR實現(xiàn)模擬Google搜索效果實現(xiàn)原理及代碼

    DWR實現(xiàn)模擬Google搜索效果實現(xiàn)原理及代碼

    本文主要介紹DWR實現(xiàn)模擬Google搜索效果實現(xiàn)原理,感興趣的朋友可以了解下,或許對你的DWR學習有幫助,閑話就不多說了,看代碼了
    2013-01-01
  • Bootstrap每天必學之導航條

    Bootstrap每天必學之導航條

    Bootstrap每天必學之導航條,本文向大家講解了多種多樣的導航條,以及導航條中元素的實現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2015-11-11
  • JS判斷字符串包含的方法

    JS判斷字符串包含的方法

    這篇文章主要介紹了JS判斷字符串包含的方法,可有效的檢測字符串中是否包含固定字符或子字符串,涉及javascript中indexOf的使用技巧,非常簡單實用,需要的朋友可以參考下
    2015-05-05
  • js獲取當前日期代碼適用于網(wǎng)頁頭部

    js獲取當前日期代碼適用于網(wǎng)頁頭部

    大家在瀏覽網(wǎng)頁時可能會注意到網(wǎng)頁頭部有個不錯的時間在顯示,看起來感覺不錯于是自己也實現(xiàn)了一個,下面是具體的代碼,感興趣的朋友可以參考下哈
    2013-06-06

最新評論