JS小知識——立即執行函式

後會有期i發表於2019-03-26

立即執行函式有哪些?

在JavaScript中,一般情況下定義一個函式需要給這個函式命名,或者建立一個變數接受一個函式,以方便之後呼叫。如果我們不需要一個命名的函式,那麼通常會使用立即執行函式(IIFE)來解決我們的問題,同時,立即執行函式有時候可以幫我們解決某些閉包問題。

例如

function test(){
    var arr = [];
    for(var i=0;i<5;i++){
        arr[i] = function(){
           console.log(i);       
        }                                        
    } 
    return arr;
} //test()執行後返回一個陣列,每一項為一個函式
複製程式碼
test().forEach((item)=>{
	item()
})  // 輸出 5 5 5 5 5
複製程式碼

如果我們想要讓test執行後的陣列每一項返回對應的i值,可以通過立即執行函式解決

function test(){
    var arr = [];
    for(var i=0;i<5;i++){
        (function(i){
            arr[i] = function(){
               console.log(i)       
            }                                      
        })(i)
    }
    return arr;
}
複製程式碼
test().forEach((item)=>{
	item()
}) //輸出0 1 2 3 4
複製程式碼

這是立即執行函式的一個應用,可以幫助我們解決部分閉包問題,還有很多用途,比如避免變數汙染,隔離作用域。最著名的還是jQuery的應用了。那麼立即執行函式有多少種寫法呢?

常見兩種形式

通過( )包裹函式體在通過( )執行函式

  1. (function(){console.log(1)}())
  2. (function(){console.log(2)})()

這兩種方式等價,通過把匿名函式體變成表示式後自執行。

通過位運算子

  1. ~function(){console.log(3)}()
  2. -function(){console.log(4)}()
  3. +function(){console.log(5)}()
  4. !function(){console.log(6)}()

這四種方式通過位運算子把函式體變成表示式之後執行會導致返回的結果發生不同。並且壓縮程式碼後產生恐怖效應所以基本不推薦使用,還有一些賦值運算

  1. var a = function(){console.log(7)}() 會導致函式自執行,包括一些邏輯運算子

  2. 1 && function(){console.log(8)}()

  3. 0 || function(){console.log(9)}() 甚至包括 new (畢竟ta也是一個運算子)也會導致函式的自執行!

在實際開發中,為了防止程式碼壓縮導致1,2方式與值錢的程式碼發生不清不楚的關係,一般會選擇在立即執行函式之前添上 ';'。不過一般在使用時很少會接收返回值,還有一個更好的推薦--void運算子。

  1. void function(){console.log(10)}()

通過void 滿足我們不用始終記得新增 ; 的痛苦~~。

OK 除了兩種常見的運用方式,有沒有覺得知道的更多了點呢。

有問題也不給你聯絡我

相關文章