# 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)