前端面試之立即執行函數


什么是立即執行函數

聲明一個函數,並馬上調用這個匿名函數就叫做立即執行函數。在定義好一個函數后,直接執行。

(function() {alert('立即執行函數')})() 

用聲明一個函數,用括號包起來,調用此函數。

立即執行函數的寫法

有時候,我們定義函數以后,立即調用該函數,這時不能在函數的定義后面直接加圓括號,這會產生語法錯誤。產生語法錯誤的原因是,function這個關鍵字,既可以當做語句,也可以當做表達式。

//語句
function fn() {};

//表達式
var fn = function(){};

規定:如果function出現在行首,一律解析成語句。行首是function關鍵字時,這一段都是函數定義,不應該以圓括號結尾,所以會報錯。當不讓function出現在行首時,這將被理解為一個表達式,最簡單的處理方式就是將其放在一個圓括號里。

(function() {
    ...
}())

(function() {
    ...
})()

以圓括號開頭,這將被理解為表達式,而不是一個函數定義語句,所以就避免了錯誤,這就叫“立即執行函數”。
其他的寫法:

(function() {alert('匿名函數')}())	//用括號將整個表達式包起來
(function() {alert('匿名函數')})()	//用括號將函數包起來
!function() {alert('匿名函數')}()	
+function() {alert('匿名函數')}()
-function() {alert('匿名函數')}()
~function() {alert('匿名函數')}()
void function() {alert('匿名函數')}()
new function() {alert('匿名函數')}()

立即執行函數的作用

1、不必為函數命名,避免了污染全局變量。

2、立即執行函數內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。

3、封裝變量。

面試題

var list = document.getElementById("list");
var li = list.children;
for(var i = 0 ;i<li.length;i++){
  li[i].onclick=function(){
    alert(i);  // 結果總是3.而不是0,1,2
    }
}

因為i是貫穿整個作用域的,而不是給每一個li分配一個i,點擊事件使異步用戶一定是在for運行完以后才點擊,此時i已經變成3了。

解決方法:

1、使用立即執行函數,給每個li創建一個獨立的作用域,在立即執行函數執行的時候,i的值從0到2,對應三個立即執行函數,所以就能正常輸出了。

var list = document.getElementById("list");
    var li = list.children;
    for(var i = 0 ;i<li.length;i++){
      (function(j) {li[j].onclick=function(){
        alert(j);  // 結果是0,1,2
      }})(i)
    }

2、使用ES6的塊級作用域

var list = document.getElementById("list");
var li = list.children;
for(let i = 0 ;i<li.length;i++){
  li[i].onclick=function(){
    alert(i);  // 結果總是3.而不是0,1,2
    }
}

立即執行函數的使用場景

1、代碼在頁面加載完成之后,不得不執行一些設置工作,比如時間處理器,創建對象等等。

2、所有的這些動作只需要執行一次,比如只需要顯示一個事件。

3、將代碼包裹在它的局部作用域中,不會讓任何變量泄漏成全局變量。

立即執行函數的參數

(function(i) {
    ...
})(j)

如果立即執行函數中需要全局變量,全局變量會被作為一個參數傳遞給立即執行函數。j代表是實參,i代表的是執行函數的形參。

立即執行函數的作用

1、改變變量的作用域(創建一個獨立的作用域)。

2、封裝臨時變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM