# 匿名函式典型的使用時機

## 1. 模組封裝
老師之前展示MVC架構的例子其中一部分
```+
let models={
data:null,
removeProductData:function(name){
this.data=this.data.filter((product)=>{
return product.name!==name;
});
},
getProductData:function(){
let url="https://cwpeng.github.io/live-records-samples/data/products.json";
return fetch(url).then((response)=>{
return response.json();
}).then((result)=>{
this.data=result;
});
}
};
```
## 2. 沒有被使用在其他地方的callback functions
優點:當處理程序在定義並且呼叫他們時,保持code的獨立性和可讀性,不用再到其他地方找函數。
```+
setTimeout(function () {
console.log('Hello world!');
}, 1000);
```
```+
window.navigator.geolocation.getCurrentPosition(
position => console.log(position.coords.latitude,position.coords.longitude),
err => console.log(err.message)
)
```
## 3.使用IIFE封裝,使得內部變數不影響全域變數
``` +
(function () {
// Some code here.
})();
(x => x * x)(10)
```
## 4.pure function
```+
const arr = [1, 2, 3];
const double = arr.map(function (el) {
return el * 2;
});
console.log(double); // [2, 4, 6]
```
## 補充1 - IIFE的應用
### 在五秒鐘內,每秒鐘依序透過console.log印出:0 1 2 3 4
我會想到用for迴圈+setTimeout
```+
for(var i=0;i<5;i++){
window.setTimeout(function(){
console.log(i)
},1000*i)
}
// 5,5,5,5,5
```
但是這樣的結果會造成console.log在每秒鐘都印出5
for迴圈不會等window.setTimeout結束後才繼續,而是在執行階段就一口氣跑完。
當window.setTimeout內的callback function執行時,拿到的i已經是跑完for迴圈的5。
**可以使用IIFE包裝window.setTimeout**
```+
for(var i=0;i<5;i++){
(function(i){
window.setTimeout(function(){
console.log(i)
},1000*i)
})(i)
}
// 0,1,2,3,4
```
**或是改用let,保留i在執行迴圈當下的「值」的效果**
```+
for(let i=0;i<5;i++){
window.setTimeout(function(){
console.log(i)
},1000*i)
}
// 0,1,2,3,4
```
## 補充2 - void運算子
#### void只有一個功能,就是接收任意的運算式或值,回傳undefined。
用法和typeof一樣,可以在後面加上小括號(),或是直接加上某個值:
```+
void 0; // undefined
void(0) // undefined
```
如果在void後面加上IIFE,即使函式有名字
```+
void function sayHello(msg){
console.log(msg)
}('Hello')
// 'Hello'
```
也還是會印出'Hello'
但若我們嘗試去呼叫sayHello函式,會得到函式未定義的錯誤訊息
```+
void function sayHello(msg){
console.log(msg)
}('Hello')
sayHello('I don\'t wanna say Hello.')
// Uncaught ReferenceError: sayHello is not defined
```
實際應用情境不多,有些開發者會在此類一次性呼叫的IIFE前面加上void,增加程式碼可讀性。
---
參考資料
| Features | Tutorials |
| ----------------- |:----------------------- |
| front-end-interview-handbook | [:link:][front-end-interview-handbook] |
| 重新認識JavaScript(5-21) | |
| What is a typical usecase for anonymous functions? | [:link:][anonymous-functions] |
| JavaScript: Functional Programming 函式編程概念 | [:link:][fp] |
[front-end-interview-handbook]: https://github.com/yangshun/front-end-interview-handbook/blob/master/contents/en/javascript-questions.md#whats-a-typical-use-case-for-anonymous-functions
[anonymous-functions]: https://www.quora.com/What-is-a-typical-usecase-for-anonymous-functions
[fp]: https://totoroliu.medium.com/javascript-functional-programming-%E5%87%BD%E5%BC%8F%E7%B7%A8%E7%A8%8B%E6%A6%82%E5%BF%B5-e8f4e778fc08