JavaScript 立即執行函數 IIFE (Immediately Invoked Function Expression) / Self-invoking Function

立即執行函數 (Immediately Invoked Function Expression,簡稱 IIFE) 是一個在宣告的當下就會馬上被執行的函數

語法:

(function () {
  // 寫在這裡面的程式碼
  // 會立刻被執行
})();

或把 () 移到外面也可以:

(function () {
  // 寫在這裡面的程式碼
  // 會立刻被執行
})();

IIFE 本質是一個會被立刻執行的匿名函數 (anonymous function),使用 IIFE 的一個最大好處是避免污染全域變數命名空間 (global namespace)

用法例如:

(function () {
  // foo 是一個區域變數
  var foo = 'hello world';
  // 這裡使用 var 是為了示範 function scope。
  // 當然你也可以用 let 或 const,它們在 IIFE 中也是區域變數。

  // 顯示 hello world
  alert(foo);
})();

// 這行會發生錯誤,因為 foo 變數不存在
// 意即全域變數命名空間不會被污染!
//
// Uncaught ReferenceError: foo is not defined
alert(foo);

立即執行函數可以用來減少全域變數的使用,因為在 IIFF 中的變數是區域變數,所以很常被使用來包裝只會被執行一次的程式碼,或是程式初始化的 code。

跟一般函數一樣,IIFE 可以傳參數進去,例如:

(function (w, d, $) {
  // w 是一個局部變數,指向 window 物件
  // d 是一個局部變數,指向 document 物件
  // $ 是一個局部變數,指向 jQuery 物件
})(window, document, jQuery);

在上面這個例子中,我們將全域變數 window, document, jQuery 當成參數傳遞進去立即執行函數中,除了可以在函數中使用不同的變數名稱,還有一個好處是會讓程式效能略微提升,因為 JavaScript 查找變數時,會先找區域變數找不到再去找全域變數。

跟一般函數一樣,IIFE 可以有返回值 (return value),例如:

// 將立即執行函數的返回值,指定給 foo 變數
const foo = (function () {
  // 返回一個 object
  return {
    hello: function () {
      return 'Hello';
    },
  };
})();

// 顯示 Hello
alert(foo.hello());
在現代 JavaScript 開發中 (ES6 Modules),因為 Module 本身就有獨立的檔案作用域 (Module Scope),不需要透過 IIFE 來避免全域污染。但 IIFE 在某些設計模式或還未全面模組化的環境中仍然很有用。