JavaScript基礎之立即執行函數
在JavaScript中有時候看到一些很神奇的函數比如下面截圖:
這種函數隻要瀏覽器加載的時候會自動運行,而需要調用,前面在閉包的時候也說過這種函數,一般將其稱之為:立即執行函數。
立即函數的特征:
- 會自動執行
- 隻會執行一次
立即執行函數格式
立即執行函數一般有格式如下:
# 格式一(//W3C 推薦這種寫法) (function (){ }()) #格式二 (但是這個才是最常用的方式之一) (function (){ })();
其實上面還可以看出立即執行函數,一般都不會寫函數名字,其意義不大,畢竟立即函數不必通過函數名進行調用瞭,這個和字面量定義函數的時候作用差不多。
現在結合閉包和立即執行函數相互結合來一個例子:
var fun=( function(){ function test(a,b){ console.log(a+b); } return test; } )()
立即執行函數其他方式–表達式
上面的立即執行函數的格式定義,但是還有其他方式實現這個功能,比如下面這個就不是上面的格式
!function(){ console.log("test"); }()
看出其輸出的兩行,第一個是test,也就是有種立即執行函數的結果,而true被輸出是是因為前面多瞭!,這個在隱式轉換的時候說過,在!後面的都會強制換行佈爾類型。
現在又有一個疑問瞭,為什麼這種方式可以實現呢?
分析這種情況的產生,首先來一個表達式函數:
var test=function(){ console.log("test表達式") } #這樣聲明後,如何使用呢?如下 test();
這個時候就有一個大膽的想法瞭,賦值的函數,通過變量值+()就可以執行,那為什麼不能直接寫好。
var test=function(){ console.log("test表達式") }()
這地方可以看出 表達式函數也有瞭一種立即執行的效果。
(補充:為什麼都有undefined,因為這個函數本身就沒有return 值,所以會有undefined這個值在瀏覽器console面板輸出瞭undefined)
那直接在函數後面放括號可以嗎?
function(){ console.log("test表達式") }()
可以看出需要用表達式前提才可以在後面放(),不然會報錯。
這個時候就有瞭一個大膽的想法,其實!後面方法,其實將函數轉換成立表達式函數,所以後面可以+()可以直接運行瞭。那就有瞭大膽的想法,既然如此那直接在函數前加一個加號(+)試試。
+function(){ console.log("test表達式") }()
既然加號可以那麼:
+ | – |
---|---|
! | ~ |
當然所謂的乘號和除號是無法實現的,還有一個神奇的關鍵字也可以有這個神奇的效果,那就是new 和 void
new function(){ console.log("test表達式") }()
還有一個那就是量邏輯運算符號 || 和&& 也可以實現
不過這個需要根據其特征再前面需要加真或者假才可以,單獨使用是不可以的
1 && function(){ console.log("test表達式") }() 或者 0 || function(){ console.log("test表達式") }()
還有一個神奇的符號(逗號)也可以實現這個功能:
1,function(){ console.log("test表達式") }()
可以看出如果使用逗號,無論前面真假都會執行後面的表達式函數。
立即執行函數可以帶參數
立即執行函數也可以有參數的,具體如下
(function(a,b){ console.log(a,b) })(1,2)
應用
這個題是很經典的面試題,首先創建下一個html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>test</title> </head> <body> <ul id=”test”> <li>這是第一條</li> <li>這是第二條</li> <li>這是第三條</li> </ul> <script> var liList=document.getElementsByTagName('li'); for(var i=0;i<liList.length;i++) { liList[i].onclick=function(){ console.log(i); } }; </script> </body> </html>
目的是點擊第幾個標簽li 輸出幾,但是結果
因為在點擊li的時候for循環早已循環完畢瞭,這個可以用前面所學的let,關鍵字也可以解決
var liList=document.getElementsByTagName('li'); for(let i=0;i<liList.length;i++) { liList[i].οnclick=function(){ console.log(i); } };
這個可以解決這個問題,但是沒有用到立即運行函數,當然也可以通過立即執行函數進行修改
var liList=document.getElementsByTagName('li'); for(let i=0;i<liList.length;i++) { (function(a){ liList[a].οnclick=function(){ console.log(a); } })(i) };
可以看出立即執行函數會形成一個自己的封閉空間,其不會被外部的其他變量影響,其實這個如果再有一個return的話就是一個標準的閉包瞭。
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- JavaScript文檔對象模型DOM
- javascript知識點詳解
- JavaScript事件概念詳解(區分靜態註冊和動態註冊)
- 初識JavaScript的基礎
- JavaScript 中的輸出數據多種方式