---
# System prepended metadata

title: IIFE 函式表示式

---

# IIFE 函式表示式

> IIFE(Immediately Invoked Function Expressions)
> 指的是可以立即執行Functuin Expressions
> 中文多譯為立即(執行)函式。

```javascript=
var hello = function(name){
	console.log('Hello ' + name);
};

hello(); // Hello undefined

```

把hello()刪掉，改成
```javascript=
var hello = function(name){
	console.log('Hello ' + name);
}(); // Hello undefined
```
電腦在函式表示式後面讀到()，就知道要立刻呼叫這個函式，這種立刻執行的函式寫法就稱為**IIFE**。

若要傳值進去可以加參數在最後面的()

```javascript=
var hello = function(name){
	console.log('Hello ' + name);
}('Simon');

// Hello Simon
```
將函式裏頭的console.log改成return，透過另一個console.log()呼叫變數指向的函式。

> 一般的函式表達式

```javascript=
var hello2 = function(name){
	return 'Hello ' + name
};
console.log(hello2); // [Function: hello2]
```
函式結尾的}後面沒有()表示立即執行，所以console.log印出hello2時，是印出hello2指向的函式

**若要傳值進去，一樣加參數在函式最後面的()**

```javascript=
var hello2 = function(name){
	return 'Hello ' + name
}('Simon');
console.log(hello2); // Hello Simon
```


```javascript=
var hello2 = function(name){
	return 'Hello ' + name
}('Simon');
console.log(hello2()); 
// TypeError: hello2 is not a function
```

hello2乍看指向立即執行函式，其實可視為指向立即執行函式的返回值Hello Simon，現在console.log()的hello2後面多加一個()，電腦就會往return回傳的'Hello ' + name去找函式，現在'Hello ' + name是字串Hello Simon，並不是函式，自然就報出錯誤囉！

```javascript=
function(food){
	console.log('大俠愛吃' + food)
}('漢堡包');
// SyntaxError: Function statements require a function name
```

因為沒有變數指向它(不是Functions Expressions)，它也沒有名子(不是Function Statement)，所以語法解析器認為這段程式寫錯了，自然報錯。

解決方法是，最外面再用一個()把它包起來

```javascript=
(function(food){
	console.log('大俠愛吃' + food)
}('漢堡包')); // 大俠愛吃漢堡包
```

```javascript=
(function(food){
	console.log('大俠愛吃' + food)
})('漢堡包');
```

這樣就不會報錯了，這也是IIFE，也是最常在JS框架、套件看到的寫法。
至於放在後面，立即呼叫的()，要放在裡面或外面都可以，兩個結果都一樣，不過作者認為開發者擇一使用就好。

另外，ES5版本的JS有全域執行環境(作用域)、函式執行環境(作用域)兩種，直到ES6版才出現塊級作用域，在ES6出來前，為了避免設定太多的全域變數，開發者往往會將變數設定在函式中，使其成為區域變數，尤其是設定在IIFE中，確保不會汙染到全域環境的變數。

```javascript=
var seafood = '波士頓龍蝦';
(function(name){
	var seafood = '北海道帝王蟹';
	console.log(name + '好~想吃' + seafood);
}('Simon')); // Simon好～想吃北海道帝王蟹
```

```javascript=
var food = '水牛城雞翅';
console.log(food);
(function(global){
    var food = '雞塊';
	global.food = '麥脆雞';
    console.log(food);
})(window);
console.log(food); 
// 水牛城雞翅
// 雞塊
// 麥脆雞
```

為避免無意義的外部查找，將window當參數傳入，使其成為這個IIFE的區域物件，確保在IIFE內的程式能故意取用到全域的特定變數。

[參考資料：Day20　立即呼叫的函式表示式(IIFE)](https://ithelp.ithome.com.tw/articles/10193313#:~:text=%E6%8C%87%E7%9A%84%E6%98%AF%E5%8F%AF%E4%BB%A5%E7%AB%8B%E5%8D%B3,%E7%AB%8B%E5%8D%B3(%E5%9F%B7%E8%A1%8C)%E5%87%BD%E5%BC%8F%E3%80%82&text=%E9%9B%BB%E8%85%A6%E5%9C%A8%E5%87%BD%E5%BC%8F%E8%A1%A8%E7%A4%BA,%E5%AF%AB%E6%B3%95%E5%B0%B1%E7%A8%B1%E7%82%BAIIFE%E3%80%82)