# 匿名函式典型的使用時機 ![image alt](https://i.imgur.com/otobEI1.png =400x250) ## 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