iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
自我挑戰組

重新開始 JavaScript系列 第 29

[Day29] 立即函式 IIFE

立即函式簡介

立即函式 IIFE (Immediately Invoked Function Expression),是可以立即執行的函式表達式,大部分情況下立即函式不需要定義名稱,以下為基本的立即函式:

// 具名函式的立即函式
(function fun() {
    console.log('IIFE');
}());

// 匿名函式的立即函式
(function () {
    console.log('IIFE');
}());

小括號位子也可移至最後,如下範例所示:

// 具名函式的立即函式
(function fun() {
    console.log('IIFE');
})();

// 匿名函式的立即函式
(function () {
    console.log('IIFE');
})();

而立即函式主要有以下特點:

  1. 立刻執行

    立即函式不需要另外呼叫函式也可以立即執行

  2. 無法在函式外被再次執行

    立即函式就算是具名函式,在函式外也無法被呼叫

    (function fun() {
        console.log('IIFE');
    }());
    
    // IIFE
    
    fun(); // 錯誤訊息 - Uncaught ReferenceError: fun is not defined
    
  3. 立即函式式函式表達式

    立即函式因為是表達式,會回傳值,所以可以將此值賦予到變數上

    var callName = (function (nickName) {
        return nickName;
    }('Carol'));
    
    console.log(callName); // Carol
    

透過立即函式限制變數的作用域

因變數的作用域在函式內,所以可以透過立即函式限制變數的作用域

以下範例中,在立即函式內宣告 變數 nickName,因變數的作用域在函式內,所以 變數 nickName 只能在此函式內被取得

(function () {
    var nickName = 'Carol'
    console.log(nickName);
}());

// Carol

console.log(nickName); // 錯誤訊息 - Uncaught ReferenceError: nickName is not defined

透過立即函式傳遞參數

立即函式一般函式一樣可以傳遞參數

(function (nickName) {
    console.log(nickName);
}('Carol'));

// Carol

利用傳參考特性使立即函式傳遞內容

雖然立即函式很常用來限制作用域,但有時常需要把立即函式裡的內容傳到另一個立即函式內,這時可以利用物件的傳參考特性,範例如下:

  • 先宣告一個 變數 a,此 變數 a 指向一個空的物件,讓 變數 a 為第一個立即函式的參數,則 參數 b 會與 變數 a 指向同一個物件參考路徑,所以就算增加物件內屬性,參數 b變數 a 的值還是相同

  • 再讓 變數 a 為第二個立即函式的參數,參數 c 會與 變數 a 也會指向同一個物件參考路徑,所以可以看到在第一個立即函式中更改的內容

var a = {};

(function (b) {
    b.nickName = 'Carol';
}(a));

(function (c) {
    console.log(c.nickName);
}(a));

利用全域物件使立即函式傳遞內容

利用全域物件 window,將全域物件傳入參數,此參數指向此物件的參考路徑,透過全域物件來傳遞值,此方法常會用在大型框架上(ex: Vue),用以確保框架可以正確掛載到全域變數上

(function (gobal) {
    gobal.nickName = 'Carol';
}(window));

(function () {
    console.log(nickName);
}());

不發生 ASI 規則,造成的錯誤

Day10 - ASI 自動插入分號 中有提到,當新的一行是 ( 開始,不會發生 ASI 規則,無法自動插入分號,所以若相鄰的 2 個立即函式沒有用分號分隔,會被視為同一行,造成錯誤

(function () {
}())

(function () {
}())

// 錯誤訊息 - Uncaught TypeError: (intermediate value)(...) is not a function

解決方法

方法1:在立即函式後方加入分號

(function () {
}());

(function () {
}());

方法2:在立即函式前方加入分號

;(function () {
}())

;(function () {
}())

參考文獻

六角學院 - JavaScript 核心篇

MDN - IIFE


上一篇
[Day28] 函式
下一篇
[Day30] 完賽結語
系列文
重新開始 JavaScript32

尚未有邦友留言

立即登入留言