1. 程式人生 > >js匿名函式的理解

js匿名函式的理解

摘要:

定義函式的方式有兩種,一種是函式宣告,一種是函式表示式(匿名函式)。
函式宣告:

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

JavaScript無論你怎麼去定義你的函式,JS直譯器都會把它翻譯成一個Function物件。

alert(typeof abc);// “function” 

Function 物件是JavaScript裡面的固有物件,所有的函式實際上都是一個Function物件。
Function物件能不能直接運用建構函式建立一個新的函式呢?答案是肯定的。例如:

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

一、概念及案例

匿名函式顧名思義,匿名函式就是沒有實際名字的函式。例如,我們把上面的例子中,函式的名字去掉,再判斷一下他是不是一個函式

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

我們可以很容易地看到,它們全都是Function物件,換言之,他們都是函式,但是他們都有一個特點——沒有名字。所以我們把他們稱作“匿名函式”。然而,正因為他們沒有“名字”,我們也沒有辦法找到他們。這就引申瞭如何去呼叫一個匿名函式的問題了。
要呼叫一個匿名函式,我們必須要有方法定位它,引用它。所以,我們會需要幫它找一個名字。例如:

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

上面的操作其實就等於換個方式去定義函式,這種用法是我們比較頻繁遇到的。例如我們在設定一個DOM元素事件處理函式的時候,我們通常都不會為他們定名字,而是賦予它的對應事件引用一個匿名函式。
對匿名函式的呼叫其實還有一種做法,使用()將匿名函式括起來,然後後面再加一對小括號(包含引數列表)。我們再看一下以下例子:

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

上邊例子當中,小括號的作用就是把我們的表示式組合分塊,並且每一塊,也就是每一對小括號,都有一個返回值。這個返回值實際上也就是小括號中表達式的返回值。所以,當我們用一對小括號把匿名函式括起來的時候,實際上是對一對小括號返回的,就是一個匿名函式的Function物件。因此,小括號對加上匿名函式就如同有名字的函式般被我們取得它的引用位置了。所以如果在這個引用變數後面再加上引數列表,就會實現普通函式的呼叫形式。

 var sayHi=function(){alert("hi")};
   sayHi();

執行匿名函式: 給它起個名字,後面加個括號,就可以執行了。那麼也就是可以在函式後面直接加括號就可以執行,而不用給它起名了。

三、使用場景

模擬塊級作使用域,減少全域性變數。執行完匿名函式,儲存在記憶體中相對應的變數會被銷燬,從而節省記憶體。再者,在大型多人開發的專案中,用塊級作使用域,會大大降低命名衝突的問題,從而避免產生嚴重後果。自此開發者再也不必擔心搞亂全域性作使用域了。

總結:

1)匿名函式加小括號,(被小括號包含的匿名函式)可以理解為括號表示式返回的函式物件,然後就可以對這個函式物件作正常的引數列表呼叫了。
2)只有函式表示式還是不能直接呼叫函式的,去掉匿名函式括號必須要伴隨將表示式賦值。也就是(function(){alert(1)})()應該是與 a=function(){alert(1)}()等價,不能連a=都去掉。

參考:
JS中的匿名函式