問題引入:咱們寫函數,就是爲了使咱們的代碼更加模塊化,而後,提升代碼的重用。可是,有些函數,從定義到整個函數就運行了一遍。可是這個函數依然存在,就佔用了大量的內存。那有沒有一種函數,執行完了以後,就不存在了的呢?面試
聲明一個函數,並立刻調用這個匿名函數就叫作當即執行函數;也能夠說當即執行函數是一種語法,讓你的函數在定義之後當即執行;dom
當即執行函數的建立步驟,看下圖:模塊化
接下來看當即執行函數的兩種常見形式:函數
//匿名函數包裹在一個括號運算符中,後面跟一個小括號 (function(){ //... })() ////匿名函數後面跟一個小括號,整個包裹在一個括號運算符中 (function(){ //... }())
(),!,+,-,=等運算符都能起到當即執行的做用,這些運算符的做用就是將匿名函數或函數聲明轉換爲函數表達式。spa
要注意兩點,一是函數體後面要有小括號(),二是函數體必須是函數表達式而不能是函數聲明。code
(function (test) { //使用()運算符,輸出123 console.log(test); })(123); (function (test) { //使用()運算符,輸出123 console.log(test); }(123)); !function (test) { //使用!運算符,輸出123 console.log(test); }(123); var fn = function (test) { //使用=運算符,輸出123 console.log(test); }(123);
總而言之:當即執行函數會造成一個單獨的做用域,咱們能夠封裝一些臨時變量或者局部變量,避免污染全局變量。以一個面試題爲例:對象
var liList = ul.getElementsByTagName('li') for(var i=0; i<6; i++){ liList[i].onclick = function(){ alert(i) // 爲何 alert 出來的老是 6,而不是 0、一、二、三、四、5 } }
爲何 alert 的老是 6 呢,由於 i 是貫穿整個做用域的,而不是給每一個 li 分配了一個 i,以下:blog
劃重點:用戶必定是在for運行完了以後,才點擊的,此時i爲6內存
解決方案:作用域
用當即執行函數給每一個li創造一個獨立做用域便可(固然還有其餘辦法):
var liList = ul.getElementsByTagName('li') for(var i=0; i<6; i++){ !function(ii){ liList[ii].onclick = function(){ alert(ii) // 0、一、二、三、四、5 } }(i) }