立即調用函數表達式(Immediately-invoked Function Expression,簡稱IIFE)是一種立即執行函數的方式,即在函數被創建的同時立即執行。

IIFE非常有用,因為它們不會污染全局對象,並且是一種簡單的方式來隔離變量聲明。

以下是定義IIFE的語法:

(function() {
  /* code */
})()

也可以使用箭頭函數來定義IIFE:

(() => {
  /* code */
})()

我們基本上在括號內定義了一個函數,然後附加 () 來執行該函數:(/* function */)()

這些包裹括號實際上使我們的函數內部被視為表達式。否則,函數聲明將無效,因為我們沒有指定任何名稱:

無效的函數聲明

函數聲明需要一個名稱,而函數表達式不需要。

您還可以將調用的括號放在表達式括號內部,這沒有區別,只是一種風格上的偏好:

(function() {
  /* code */
}())

(() => {
  /* code */
}())

使用一元運算符的替代語法

有一些更奇怪的語法可以用來創建IIFE,但在現實世界中很少使用,它依賴於使用任意一元運算符:

-(function() {
  /* code */
})() +
 (function() {
  /* code */
 })()

~(function() {
  /* code */
})()

!(function() {
  /* code */
})()

(對於箭頭函數不起作用)

命名的 IIFE

IIFE 也可以是帶有名稱的常規函數(非箭頭函數)。這不會改變函數不會“洩漏”到全局作用域並且在執行後無法再次調用的事實:

(function doSomething() {
  /* code */
})()

以分號開始的 IIFE

你可能在現實場景中見過這種寫法:

;(function() {
  /* code */
})()

這可以避免當兩個 JavaScript 文件盲目連接在一起時出現問題。由於 JavaScript 不需要使用分號,你可能會連接一個具有語句在最後一行的文件,這會造成語法錯誤。

這個問題基本上通過“智能”代碼捆綁器(如 webpack)解決了。