[JS奇怪的世界]No.36 立即呼叫的函數表示式(IIFEs)

前言

立即呼叫的函數表示式又稱為 IIFE,相信許多人已經知道這個東西,但實際 IIFE 是什麼,它是怎樣運作,又有什麼用,這就是本章節要探討的問題。

函數陳述句與函數表示式

首先我們都已經知道函數陳述句與函數表示式的差異。

而這就是函數陳述句,當 JavaScript 執行完畢後只會將它放在記憶體中,並不會執行它,除非我們執行了 greet()

1
2
3
4
5
function greet() {
console.log('Hello');
}

greet();

然而函數表示式就像這樣,它一開始並不會被儲存到記憶體內,只有變數會被儲存至記憶體內,因為變數有提升效果,直到 JavaScript 執行這一行時就會立刻創造執行環境,這就是函數表示式。

1
2
3
4
5
var greetFunction = function() {
...
};

greetFunction();

IIFE

簡單回顧了之前的函數陳述句與函數表示式後,我們可以對函數做一點特別的動作,讓它變成特別的物件,若我們希望在函數表示式後立刻呼叫它,而不是透過 greetFunction(); 呢?

1
2
3
var greetFunction = function() {
console.log('Hi');
}();

只需要在後面加上括號就可以了,那如果我們帶入參數應該放哪?一樣在括號裡面帶入就好了。

1
2
3
var greetFunction = function(name) {
console.log('Hi ' + name);
}('Jack');

IIFE

而這觀念就是它會在函數被創造之後立刻呼叫它(執行),而這就是人家講的立即呼叫的函數表示式又稱 IIFE。

所以我們可以看看這兩者差異在哪裡。

1
2
3
4
5
6
7
8
9
10
11
var greetFunctionTwo = function(name) {
console.log('Hi ' + name);
};
console.log(greetFunctionTwo);

// IIEF
var greetFunction = function(name) {
console.log('Hi' + name);
}();

console.log(greetFunction);

IIFE

我們可以發現不是使用 IIFE 會得到一整個函數,而 IIFE 直接會得到一個值,這也就是這兩者差異。

當然也有另一種撰寫方式。

1
2
3
(function(name) {
console.log('Hi' + name)
})('Jack');

![]IIFE(https://i.imgur.com/aURma5S.png)

這也是人家講的匿名函數,我不需要名稱就可以直接執行的函數。

但若如果這樣呢?

1
2
3
function(name) {
console.log('Hi' + name)
}

你會得到一個錯誤。

因為當語法解析器第一行解析到 f-u…. 就會一直解析,而它就會想說 「哦!這是一個函數陳述句,所以等一下應該會有一個名稱」,結果我們並沒有給予函數名稱,所以就會得到一個錯誤。

那如果不要讓語法解析器認為這是一個函數陳述句,那就要在函數陳述句外圍包上括號,當它解析到括號,它就會知道 「哦!這是一個函數表示式」,就像前面講的範例一樣。

1
2
3
(function(name) {
console.log('Hi' + name)
})

但是如果試著將這段程式碼貼上去執行會看到一個滿有趣的狀況。

它直接回傳一個函數,所以如果我們要正確呼叫它就在最後加上括號,而括號內也可以帶上參數。

1
2
3
(function(name) {
console.log('Hi' + name);
})('Jack');

參數

最後補充一個課程講得地方,這兩者 IIFE 都是一樣合理正確的,純粹只是美感問題。

1
2
3
4
5
6
7
(function(name) {
console.log('Hi' + name);
})('Jack');

(function(name) {
console.log('Hi' + name);
}('Jack'));

只是美感問題

圖源

JavaScript 全攻略:克服 JS 奇怪的部分

0%