JavaScript基礎(chǔ)之立即執(zhí)行函數(shù)
在JavaScript中有時候看到一些很神奇的函數(shù)比如下面截圖:

這種函數(shù)只要瀏覽器加載的時候會自動運(yùn)行,而需要調(diào)用,前面在閉包的時候也說過這種函數(shù),一般將其稱之為:立即執(zhí)行函數(shù)。
立即函數(shù)的特征:
- 會自動執(zhí)行
- 只會執(zhí)行一次
立即執(zhí)行函數(shù)格式
立即執(zhí)行函數(shù)一般有格式如下:
# 格式一(//W3C 推薦這種寫法)
(function (){
}())
#格式二 (但是這個才是最常用的方式之一)
(function (){
})();
其實(shí)上面還可以看出立即執(zhí)行函數(shù),一般都不會寫函數(shù)名字,其意義不大,畢竟立即函數(shù)不必通過函數(shù)名進(jìn)行調(diào)用了,這個和字面量定義函數(shù)的時候作用差不多。
現(xiàn)在結(jié)合閉包和立即執(zhí)行函數(shù)相互結(jié)合來一個例子:
var fun=(
function(){
function test(a,b){
console.log(a+b);
}
return test;
}
)()

立即執(zhí)行函數(shù)其他方式–表達(dá)式
上面的立即執(zhí)行函數(shù)的格式定義,但是還有其他方式實(shí)現(xiàn)這個功能,比如下面這個就不是上面的格式
!function(){
console.log("test");
}()

看出其輸出的兩行,第一個是test,也就是有種立即執(zhí)行函數(shù)的結(jié)果,而true被輸出是是因為前面多了!,這個在隱式轉(zhuǎn)換的時候說過,在!后面的都會強(qiáng)制換行布爾類型。
現(xiàn)在又有一個疑問了,為什么這種方式可以實(shí)現(xiàn)呢?
分析這種情況的產(chǎn)生,首先來一個表達(dá)式函數(shù):
var test=function(){
console.log("test表達(dá)式")
}
#這樣聲明后,如何使用呢?如下
test();

這個時候就有一個大膽的想法了,賦值的函數(shù),通過變量值+()就可以執(zhí)行,那為什么不能直接寫好。
var test=function(){
console.log("test表達(dá)式")
}()

這地方可以看出 表達(dá)式函數(shù)也有了一種立即執(zhí)行的效果。
(補(bǔ)充:為什么都有undefined,因為這個函數(shù)本身就沒有return 值,所以會有undefined這個值在瀏覽器console面板輸出了undefined)
那直接在函數(shù)后面放括號可以嗎?
function(){
console.log("test表達(dá)式")
}()

可以看出需要用表達(dá)式前提才可以在后面放(),不然會報錯。
這個時候就有了一個大膽的想法,其實(shí)!后面方法,其實(shí)將函數(shù)轉(zhuǎn)換成立表達(dá)式函數(shù),所以后面可以+()可以直接運(yùn)行了。那就有了大膽的想法,既然如此那直接在函數(shù)前加一個加號(+)試試。
+function(){
console.log("test表達(dá)式")
}()

既然加號可以那么:
| + | - |
|---|---|
| ! | ~ |
當(dāng)然所謂的乘號和除號是無法實(shí)現(xiàn)的,還有一個神奇的關(guān)鍵字也可以有這個神奇的效果,那就是new 和 void
new function(){
console.log("test表達(dá)式")
}()

還有一個那就是量邏輯運(yùn)算符號 || 和&& 也可以實(shí)現(xiàn)
不過這個需要根據(jù)其特征再前面需要加真或者假才可以,單獨(dú)使用是不可以的
1 && function(){
console.log("test表達(dá)式")
}()
或者
0 || function(){
console.log("test表達(dá)式")
}()

還有一個神奇的符號(逗號)也可以實(shí)現(xiàn)這個功能:
1,function(){
console.log("test表達(dá)式")
}()

可以看出如果使用逗號,無論前面真假都會執(zhí)行后面的表達(dá)式函數(shù)。
立即執(zhí)行函數(shù)可以帶參數(shù)
立即執(zhí)行函數(shù)也可以有參數(shù)的,具體如下
(function(a,b){
console.log(a,b)
})(1,2)

應(yīng)用
這個題是很經(jīng)典的面試題,首先創(chuàng)建下一個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>
目的是點(diǎn)擊第幾個標(biāo)簽li 輸出幾,但是結(jié)果

因為在點(diǎn)擊li的時候for循環(huán)早已循環(huán)完畢了,這個可以用前面所學(xué)的let,關(guān)鍵字也可以解決
var liList=document.getElementsByTagName('li');
for(let i=0;i<liList.length;i++)
{
liList[i].οnclick=function(){
console.log(i);
}
};

這個可以解決這個問題,但是沒有用到立即運(yùn)行函數(shù),當(dāng)然也可以通過立即執(zhí)行函數(shù)進(jìn)行修改
var liList=document.getElementsByTagName('li');
for(let i=0;i<liList.length;i++)
{ (function(a){
liList[a].οnclick=function(){
console.log(a);
}
})(i)
};

可以看出立即執(zhí)行函數(shù)會形成一個自己的封閉空間,其不會被外部的其他變量影響,其實(shí)這個如果再有一個return的話就是一個標(biāo)準(zhǔn)的閉包了。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
javascript創(chuàng)建和存儲cookie示例
javascript創(chuàng)建和存儲cookie,cookie是存儲于訪問者的計算機(jī)中的變量,下面看一下使用示例吧2014-01-01
基于JavaScript自定義構(gòu)造函數(shù)的詳解說明
本篇文章小編為大家介紹,基于JavaScript自定義構(gòu)造函數(shù)的詳解說明。需要的朋友參考下2013-04-04
js修改地址欄URL參數(shù)解決url參數(shù)問題
現(xiàn)在做網(wǎng)頁,經(jīng)常會碰到處理地址欄參數(shù)的問題,因此,就專門做了一個修改地址欄參數(shù)的方法,需要了解的朋友可以參考下2012-12-12
Javascript學(xué)習(xí)筆記之?dāng)?shù)組的遍歷和 length 屬性
我們一般用循環(huán)來遍歷數(shù)組,而循環(huán)一直是 JavaScript 性能問題的常見來源,有時循環(huán)用得不好會嚴(yán)重降低代碼的運(yùn)行速度。數(shù)組的屬性可以分為三種:length屬性,索引屬性,其他屬性.和普通對象相比,數(shù)組對象特殊的地方就是它的length屬性和索引屬性。2014-11-11
THREE.JS入門教程(6)創(chuàng)建自己的全景圖實(shí)現(xiàn)步驟
Three.js是一個偉大的開源WebGL庫,WebGL允許JavaScript操作GPU,在瀏覽器端實(shí)現(xiàn)真正意義的3D,全景圖非???。使用Three.js做一個屬于自己的全景圖并不是那么困難,感興趣的朋友可以了解下啊,希望本文對你有所幫助2013-01-01
javascript學(xué)習(xí)筆記(十八) 獲得頁面中的元素代碼
javascript學(xué)習(xí)筆記之獲得頁面中的元素代碼,需要的朋友可以參考下2012-06-06

