本文實例分析了js中匿名函數的創建與調用方法。分享給大家供大家參考。具體實現方法如下:
匿名函數就是沒有名字的函數了,也叫閉包函數(closures),允許 臨時創建一個沒有指定名稱的函數。最經常用作回調函數(callback)參數的值,很多新手朋友對于匿名函數不了解。這里就來分析一下。
function 函數名(參數列表){函數體;}
如果是創建匿名函數,那就應該是:
function(){函數體;}
因為是匿名函數,所以一般也不會有參數傳給他。
為什么要創建匿名函數呢?在什么情況下會使用到匿名函數。匿名函數主要有兩種常用的場景,一是回調函數,二是直接執行函數。
回調函數,像ajax的異步操作,就需要回調函數。這里就不詳解。關于直接執行函數,我看一個例子就明白了:
下面,我們先初步了解一下和匿名函數相關的概念。
函數聲明(function 語句),要使用一個函數,我們就得首先聲明它的存在。而我們最常用的方式就是使用function 語句來定義一個函數,如:
當然,你的函數也可以是帶參數的,甚至是帶返回值的。
但是,無論你怎么去定義你的函數,JS 解釋器都會把它翻譯成一個Function 對象。例如,你在定義上面的其中一個例子的函數號,再輸入如下代碼:
你的瀏覽器就會彈出提示框,提示你abc 是一個Function 對象。那么Function 對象究竟是什么呢?
Function 對象
Function 對象是JavaScript 里面的固有對象,所有的函數實際上都是一個Function 對象。我們先看看,Function 對象能不能直接運用構造函數創建一個新的函數呢?答案是肯定的。例如:
聲明匿名函數
顧名思義,匿名函數就是沒有實際名字的函數。例如,我們把上面的例子中,函數的名字去掉,再判斷一下他是不是一個函數:
我們可以很容易地看到,它們全都是Function 對象,換言之,他們都是函數,但是他們都有一個特點―― 沒有名字。所以我們把他們稱作“ 匿名函數” 。然而,正因為他們沒有“ 名字” ,我們也沒有辦法找到他們。這就引申了如何去調用一個匿名函數的問題了。
匿名函數的調用
要調用一個函數,我們必須要有方法定位它,引用它。所以,我們會需要幫它找一個名字。例如:
上面的操作其實就等于換個方式去定義函數,這種用法是我們比較頻繁遇到的。例如我們在設定一個DOM 元素事件處理函數的時候,我們通常都不會為他們定名字,而是賦予它的對應事件引用一個匿名函數。
對匿名函數的調用其實還有一種做法,也就是我們看到的jQuery 片段―― 使用() 將匿名函數括起來,然后后面再加一對小括號(包含參數列表)。我們再看一下以下例子:
很多人或許會奇怪,為什么這種方法能成功調用呢?覺得這個應用奇怪的人就看一下我以下這段解釋吧。
大家知道小括號的作用嗎?小括號能把我們的表達式組合分塊,并且每一塊,也就是每一對小括號,都有一個返回值。這個返回值實際上也就是小括號中表達式的返回值。所以,當我們用一對小括號把匿名函數括起來的時候,實際上小括號對返回的,就是一個匿名函數的Function 對象。因此,小括號對加上匿名函數就如同有名字的函數般被我們取得它的引用位置了。所以如果在這個引用變量后面再加上參數列表,就會實現普通函數的調用形式。
不知道以上的文字表述大家能不能看明白,如果還是理解不了的話,再看一下以下的代碼試試吧。
PS :constructor 是指創建對象的函數。也就是函數對象所代表的函數體。
總之,將其(被小括號包含的匿名函數)理解為括號表達式返回的函數對象,然后就可以對這個函數對象作正常的參數列表調用了。(前面這里犯了個錯誤,只有函數表達式還是不能直接調用函數的,去掉匿名函數括號必須要伴隨將表達式賦值。也就是(function(){alert(1)})() 應該是與 a=function(){alert(1)}() 等價,不能連a= 都去掉。)
閉包
閉包是什么?閉包是指某種程序語言中的代碼塊允許一級函數存在并且在一級函數中所定義的自由變量能不被釋放,直到一級函數被釋放前,一級函數外也能應用這些未釋放的自由變量。
怎樣?看得一頭冒汗吧…… 沒事,我也是(雖然是我是了解的,只是表達能力的問題)。讓我們換個更加簡單的方法說明:閉包,其實是一種語言特性,它是指的是程序設計語言中,允許將函數看作對象,然后能像在對象中的操作般在函數中定義實例(局部)變量,而這些變量能在函數中保存到函數的實例對象銷毀為止,其它代碼塊能通過某種方式獲取這些實例(局部)變量的值并進行應用擴展。
不知道這么再解釋后會否更加清晰,如果還是不明白,那么我們再簡化一下:閉包,其實就是指程序語言中能讓代碼調用已運行的函數中所定義的局部變量。
現在我們看一個例子:
以我的理解來說吧。是否應用了閉包特性,必須確定該段代碼有沒有最重要的要素:未銷毀的局部變量。那么很顯然,沒有任何實現的匿名函數不可能應用了閉包特性。但如果匿名函數里面有實現呢?那也還得確定它的實現中有沒有 用到那些未銷毀的局部變量。所以如果問你那個開篇中的jQuery 代碼片段是應用了JS 里的什么特性?那么它只是匿名函數與匿名函數的調用而已。但是,它 隱含了閉包的特性,并且隨時可以實現閉包應用。
最常見的用法:
希望本文所述對大家的javascript程序設計有所幫助。
新聞熱點
疑難解答