[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


<<:  影音串流辛酸史

>>:  Day 29: 来讲一下commit前的小撇步

Day30-2 - GitLab CI 还可以怎麽重构及整理 .gitlab-ci.yml ?

上一篇举了一个小例子来说明,一般遇到比较冗长的 .gitlab-ci.yml 大致上可以怎麽思考整理...

[Day 04] C#轻松取得IV值&实作SHA256 - [C#]丰收款API必备前置作业(三)

先来复习一下: 昨天做的是取得Nonce及HashID的部分,今天就来讲要怎麽算IV值吧! 既然顺利...

感谢此时此刻的自己 - 30天完赛

我喜欢艺术,也喜欢程序码 一开始因为工作关系强迫自己要学会程序码,原本不能接受,甚至觉得我没有天份在...

Vue.js 从零开始:watch

watch监听器 监听data里面的值,当值有变化时,就会触发事件。 watch监听一个变数: &l...

Day8 Vue Computed vs Method

我们在模板中要进行计算或转换资料时computed及method通常能做到一样的效果,这麽说的话那不...