# 4/14 + 4/21 討論總結 主講:謝時銘 參與:謝時銘、任品謙、黃暐程、李承儒 紀錄:任品謙、謝時銘 ## 1. arrow function 跟 一般function差異是什麼 一般 func 就有兩種定義方式 ```javascript= function xxx(number) { return number * number } var xxx = function(number) {return number * number}; ``` 差別在於第一種方式會自動提升到檔案開頭被優先編譯(Js 是直譯式語言),第二種不會。 箭頭函式的語法是這樣 ```javascript= var xxx = () => this.number*this.number ``` 跟一般函式差別在於 1. 簡短 2. 動態綁定 一般的函式在生成時就會因為閉包的特性把當前函式內的參數綁定下來,箭頭的話可以在呼叫時動態的綁定到對應作用域的參數。 ![](https://i.imgur.com/0NABl3c.jpg) ## 2. css auto prefixer在做什麼 自動載入補全不同 browser 下支援的不同 CSS 宣告名稱 存檔時會自動補上不同平台的前綴 ## 3. 將畫面中的球從左邊移動到右邊,可以用js,也可以用css,最大的差異為何,效能何者較好 ![](https://i.imgur.com/8uTBpoJ.jpg) ## 4. 面試的那4題javascript考題 ### 4-1. 輸出 5, 6, 7 ,8 因為 var 的生命週期是整個 function,會導致閉包截下來的是銷毀前的最後模樣,就是 5 延伸思考,那為什麼用 let 的話就會變成第一個 button 是 0 第二個是 1 的狀況? 難道 for 每執行一次都會重新銷毀創建一次該變數嗎? 參考 https://blog.techbridge.cc/2018/12/08/javascript-closure/ 因為 let 的特性,所以其實迴圈每跑一圈都會產生一個新的作用域。 應該跟我們推測的一樣,for 裡面每次執行都是一個完整的 scope 。 ### 4-2. promise 執行的順序是否為不確定行為 雖然 promise 意在做到非同步的行為,但並發後面的線程模型到底是怎麼實做的會決定輸出的順序,我們沒找到 js 有定義這部份的行為,這樣看起來 4 跟 6 的順序更像是 undefine behavior ![](https://i.imgur.com/g5EJZDT.jpg) ### 4-3. #### 題目 Write a function of the native String object for repeating a string with a specific count. ```javascript= //TODO 'foo'.repeat(3);//foofoofoo ``` 這題面試官有給提示要用Prototype Chain去解 因此要先去了解何謂Prototype Chain #### Prototype Chain 由於javascript沒有class以及子、父類的概念,但是javascript都是以object為基礎建立的 因此必須要有個機制連結object,就產生了prototype chain。 以往的物件導向語言想要共用某個property或是method都會使用繼承 javascript若是想共用或是自訂的話要用.prototype來實現。 #### 解題 像是這題要在原生的String內寫個function來重複字串輸出的作法如下 ```javascript= String.prototype.repeat = function (count){ let str = ''; let temp = this; for(let i = 0; i < count; i++){ str += temp; } console.log(str); } 'foo'.repeat(3); ``` 使用prototype chain就可以直接新增function來使用了 附上實作測試用的jsfiddle: https://jsfiddle.net/bevis00/8j759hd0/ ### 4-4 #### 題目 Write a sort function to sort data follow these rules. * 'q' is before 't' * order by label in each group ```javascript= const d = [ {type: 'q', label:9}, {type: 't', label:1}, {type: 'q', label:2}, {type: 'q', label:3}, {type: 't', label:2}, {type: 'q', label:5}, {type: 't', label:8}, {type: 't', label:4} ]; //TODO d.sort(sortFn); ``` #### sort() sort()會對陣列內的所有元素進行昇冪排序,是根據元素的Unicode編碼進行排序 若元素皆為字串的話,排序則會依據開頭字母進行排序。 可在sort()的括號內放入function,function有兩個參數比較,例如:function(a, b) 會根據當前元素a以及下一個元素b進行比較,可給定回傳值,若是回傳值<0則a會排在b前面,>0則a會排b後面,=0則不會改變彼此順序。 #### 解題 我將排序分為三次進行 1. 先對type進行排序,將type為q的元素排在type為t的前面 2. 對type為q的元素進行label排序 3. 對type為t的元素進行label排序 ```javascript= const d = [ {type: 'q', label:9}, {type: 't', label:1}, {type: 'q', label:2}, {type: 'q', label:3}, {type: 't', label:2}, {type: 'q', label:5}, {type: 't', label:8}, {type: 't', label:4} ]; function sortFn() { d.sort(function(a, b) { return a.type > b.type ? 1 : -1; }); d.sort(function(a, b) { if (a.type === 'q' && b.type === 'q') return a.label - b.label; }); d.sort(function(a, b) { if (a.type === 't' && b.type === 't') return a.label - b.label; }); } d.sort(sortFn); ``` 附上實作測試用的jsfiddle: https://jsfiddle.net/bevis00/hs709bvq/ ## 額外補充: 謝:我講一下最近用的 git flow ![](https://i.imgur.com/doLMNBJ.jpg) 謝:任你跟我解釋一下 WebSocket ,我對照一下我的理解對不對。 WebSocket 的意思 Web 打的協議依賴於 browser 的實作, WebSocket 是一種實作 http 升級到 TCP 的 API ,通常使用方式為先建立一個 http 連線之後用 browser 的 upgrade API 來升級為 WebSocket WebSocket 的特色是本身為 tcp 的雙向連線,server 和 client 都可以主動向對方傳送資料。 雖然 API 有提供 onclose 的 callback 參數,但會不會真的被觸發還是要看 browser 的底層實作,為了保證一定可以確認連線的狀態,通常會自行實作斷線檢測。 任:我解釋一下併發跟並行的差別 並發跟並行的差別 並發只是利用一些規劃、中斷和繼續來「模擬」出同時進行多個任務,跟使用的線程數量無關,最典型的就是 socket poll 並行就真的是在不同的 thread 上「同時執行」多個 thread 了,不過其實我們平常用的都已經是「輕量級線程」了,所以都不是物理上真的多個 thread ,而是 OS 封裝好的並發行為。 ![](https://i.imgur.com/4TdBAzF.jpg) ## 物件導向三技巧 繼承 組合 界面 ![](https://i.imgur.com/lEDBI1D.jpg)