# JS(4/10) Day 15 五倍紅寶石(第八屆共筆)(2021/7/16) ## 函式: ### lexical scope: 執行高等函式時,裡面的 a 函式裡沒被定義的 x 變數會去找原本被定義那邊的外層,而不是呼叫 a 函式的外層。 ```js= // console.log(x)的 x 會去找到 there,而不是 here。 var x = "there" function a() { console.log(x) } function b() { var x = "here" a() } b() ``` --- ## statement 陳述句 vs expression 表達句 statement = expression * n - statement:一個完整句子,可以表達完整的意思。 沒有回傳值 - Function statement:function a( ) { } - if - expression:單字、片語,細分句子內容成最小語意。 有回傳值 Function expression:const a = function( ) { } function( ) { } 為 a 的回傳值。 --- ## first-class citizen 一等公民 JS的function是物件,其他程式則不一定,Ruby 的 Method 不是物件。 function等同其他物件,把他當一般物件就好。 --- ## callback funciton(回呼函數) 還在等待呼叫的函數,沒有人叫他他就不會動,把 a function 傳進去 b function,待會呼叫。 ```js= function b(callback) { return callback() } const cb = () => { return console.log("123") } b(cb) // 回傳 123 ``` --- ## higher-order function(函數/函式) 可以傳入一個或多個函式或是回傳一個別的函式。 --- ## IIFE (伊FI) - Immediately Invoked Function Expression 馬上定義,馬上執行,做完泡泡就破了。 Why? 當這個函式只想在這邊使用,不想保留到其他地方的時候可以用。 不僅不會不小心汙染外面的變數,或是因為名字一樣而出錯,還可以省記憶體,很方便。 ```js= ( function() {} )() // 前面的()是匿名函式,且用來防止 function 裡面宣告的變數汙染到外面變成全域變數。 // 後面的()是用來立即呼叫函式 // 本身是一個匿名函式 // 因為泡泡馬上就破掉的關係,所以使用匿名函式很合理 // 如果要定義一個以後會用到的函式就不要用 IIFE,只是多此一舉而已 ``` jQuery 是個大 IIFE,想走前端有空可以看看。 --- ## Sync (同步) and Async (非同步) JS本質為Sync,一次只能做一件事,使用的資料結構為 stack 堆疊(後進後出)。 如果用函式讓他一直循環,到最後記憶體會滿出來,出現Ranger Error,稱做stack overflow。 跟無窮迴圈不太一樣,無窮迴圈只會卡住,不會噴錯誤訊息。 Async 非同步執行: 不會通通都卡在 Stack 區塊,把 JS 自己該做的事做完再做瀏覽器的事。 非JS內建語法如 setTimeout 的 callback 不會卡在 stack 區塊裡,一開始會先在 stack 區塊出現,接著瞬間丟給 Runtime(執行環境) 執行,等設定的時間過了之後,接著來到 Queue 排隊區(會按照順序排列),最後等 stack 區塊裡的程式碼跑完,setTimeout 的 callback 才會跑到 stack 區塊執行結果。 ![示意圖](https://i.imgur.com/nm5byAx.png) 可參考[loupe](http://latentflip.com/loupe/?code=JC5vbignYnV0dG9uJywgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljaygpIHsKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gdGltZXIoKSB7CiAgICAgICAgY29uc29sZS5sb2coJ1lvdSBjbGlja2VkIHRoZSBidXR0b24hJyk7ICAgIAogICAgfSwgMjAwMCk7Cn0pOwoKY29uc29sZS5sb2coIkhpISIpOwoKc2V0VGltZW91dChmdW5jdGlvbiB0aW1lb3V0KCkgewogICAgY29uc29sZS5sb2coIkNsaWNrIHRoZSBidXR0b24hIik7Cn0sIDUwMDApOwoKY29uc29sZS5sb2coIldlbGNvbWUgdG8gbG91cGUuIik7!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D) - Stack and Queue ### ASI (Automatic Semicolon Insertion): 如果句子的結尾不加; JS會貼心地幫你加。 ```js= function hi() { return // 沒寫分號會自動加,導致沒有回傳值 123 } function hi() { return ( // 如果一定要換行,可以加()避免此情形 123 ) } ``` --- 狀況題1: ```js= function x() { function y() { console.log("hello") } return y() } let result = x() console.log(result) // function y() 裡面沒有 return,所以會回傳 undefined ``` 狀況題2: comma operation 會回傳最後一個逗點後的值 ```js= let x, y = (1, 2) => let x => y = (1, 2) // y 變全域變數 console.log(x) // x = undefined console.log(y) // y 會回傳( )裡最後的值 = 2 ``` --- 補充: 在JS裡沒有模除(modulo operator),只有取餘數。 14 = -5 * -3 + -1(模除) 14 = -4 * -3 + 2(餘數) --- ### Xmind: [JavaScript指令](https://www.xmind.net/m/dWZLp8) --- ###### tags: `JavaScript`