合格的中級前端工程師要掌握的 JavaScript 技巧
1.判斷物件的資料型別
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷型別來返回不同的判斷函式,一行程式碼,簡潔優雅靈活(注意傳入 type 引數時首字母大寫)
不推薦將這個函式用來檢測可能會產生包裝型別的基本資料型別上,因為 call 會將第一個引數進行裝箱操作
2. ES5 實現陣列 map 方法
值得一提的是,map 的第二個引數為第一個引數回撥中的 this 指向,如果第一個引數為箭頭函式,那設定第二個 this 會因為箭頭函式的詞法繫結而失效
另外就是對稀疏陣列的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與陣列中(感謝評論區的朋友)
3. 使用 reduce 實現陣列 map 方法
4. ES5 實現陣列 filter 方法
5. 使用 reduce 實現陣列 filter 方法
6. ES5 實現陣列的 some 方法
執行 some 方法的陣列如果是一個空陣列,最終始終會返回
false
,而另一個陣列的 every 方法中的陣列如果是一個空陣列,會始終返回
true
如果你對前端開發這門技術感興趣,這裡推薦一下我的前端學習交流群: 767273102 ,裡面都是學習前端的從最基礎的HTML+CSS+JavaScript。jQuery,Ajax,node,angular等到移動端HTML5的專案實戰的資料都有整理,送給每一位前端小夥伴。最新技術,與企業需求同步。好友都在裡面學習交流,每天都會有大牛定時講解前端技術!
7. ES5 實現陣列的 reduce 方法
因為可能存在稀疏陣列的關係,所以 reduce 實現略有點複雜,需要保證跳過稀疏元素,遍歷正確的元素和下標,有更簡潔的寫法歡迎評論區留言
8. 使用 reduce 實現陣列的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會預設指向 window 從而發生錯誤
原理通過 reduce 遍歷陣列,遇到陣列的某個元素仍是陣列時,通過 ES6 的擴充套件運算子對其進行降維(ES5 可以使用 concat 方法),而這個陣列元素可能內部還巢狀陣列,所以需要遞迴呼叫 selfFlat
同時原生的 flat 方法支援一個 depth 參數列示降維的深度,預設為 1 即給陣列降一層維度
傳入 Inifity 會將傳入的陣列變成一個一維陣列
原理是每遞迴一次將 depth 引數減 1,如果 depth 引數為 0 時,直接返回原陣列
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空物件,並將這個空物件繼承 Object.create 方法的引數,再讓子類(subType)的原型物件等於這個空物件,就可以實現子類例項的原型等於這個空物件,而這個空物件的原型又等於父類原型物件(superType.prototype)的繼承關係
而 Object.create 支援第二個引數,即給生成的空物件定義屬性和屬性描述符/訪問器描述符,我們可以給這個空物件定義一個 constructor 屬性更加符合預設的繼承行為,同時它是不可列舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到例項與例項之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設定為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函式柯里化
使用方法:
柯里化是函數語言程式設計的一個重要技巧,將使用多個引數的一個函式轉換成一系列使用一個引數的函式的技術
函數語言程式設計另一個重要的函式 compose,能夠將函式進行組合,而組合的函式只接受一個引數,所以如果有接受多個函式的需求並且需要用到 compose 進行函式組合,就需要使用柯里化對準備組合的函式進行部分求值,讓它始終只接受一個引數
借用冴羽部落格中的一個例子
11. 函式柯里化(支援佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的引數先去填充上一輪的佔位符,如果當前輪引數含有佔位符,則放到內部儲存的陣列末尾,當前輪的元素不會去填充當前輪引數的佔位符,只會填充之前傳入的佔位符
12. 偏函式
使用方法:
偏函式和柯里化概念類似,個人認為它們區別在於偏函式會固定你傳入的幾個引數,再一次性接受剩下的引數,而函式柯里化會根據你傳入引數不停的返回函式,直到引數個數滿足被柯里化前函式的引數個數
Function.prototype.bind 函式就是一個偏函式的典型代表,它接受的第二個引數開始,為預先新增到繫結函式的引數列表中的引數,與 bind 不同的是,上面的這個函式同樣支援佔位符
13. 斐波那契數列及其優化
利用函式記憶,將之前運算過的結果儲存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 物件會額外佔用記憶體
14. 實現函式 bind 方法
函式的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
-
bind 返回的函式被 new 呼叫作為建構函式時,繫結的值會失效並且改為 new 指定的物件
-
定義了繫結後函式的 length 屬性和 name 屬性(不可列舉屬性)
-
繫結後函式的原型需指向原來的函式
15. 實現函式 call 方法
原理就是將函式作為傳入的上下文引數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 型別
16. 簡易的 CO 模組
使用方法:
run 函式接受一個生成器函式,每當 run 函式包裹的生成器函式遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動呼叫 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後列印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函式防抖
leading 為是否在進入時立即執行一次, trailing 為是否在事件觸發結束後額外再觸發一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函式並重新設定一個新的定時器,直到超過規定時間自動觸發定時器中的函式
同時通過閉包向外暴露了一個 cancel 函式,使得外部能直接清除內部的計數器
18. 函式節流
和函式防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發
19. 圖片懶載入
getBoundClientRect 的實現方式,監聽 scroll 事件(建議給監聽事件新增節流),圖片載入完會從 img 標籤組成的 DOM 列表中刪除,最後所有的圖片載入完畢後需要解綁監聽事件
intersectionObserver 的實現方式,例項化一個 IntersectionObserver ,並使其觀察所有 img 標籤
當 img 標籤進入可視區域時會執行例項化時的回撥,同時給回撥傳入一個 entries 引數,儲存著例項觀察的所有元素的一些狀態,比如每個元素的邊界資訊,當前元素對應的 DOM 節點,當前元素進入可視區域的比率,每當一個元素進入可視區域,將真正的圖片賦值給當前 img 標籤,同時解除對其的觀察
20. new 關鍵字
21. 實現 Object.assign
Object.assign 的原理可以參考我另外一篇部落格
22. instanceof
原理是遞迴遍歷 right 引數的原型鏈,每次和 left 引數作比較,遍歷到原型鏈終點時則返回 false,找到則返回 true
23. 私有變數的實現
使用 Proxy 代理所有含有
_
開頭的變數,使其不可被外部訪問
通過閉包的形式儲存私有變數,缺點在於類的所有例項訪問的都是同一個私有變數
另一種閉包的實現,解決了上面那種閉包的缺點,每個例項都有各自的私有變數,缺點是捨棄了 class 語法的簡潔性,將所有的特權方法(訪問私有變數的方法)都儲存在建構函式中
通過 WeakMap 和閉包,在每次例項化時儲存當前例項和所有私有變數組成的物件,外部無法訪問閉包中的 WeakMap,使用 WeakMap 好處在於不需要擔心記憶體溢位的問題
24. 洗牌演算法
早前的 chrome 對於元素小於 10 的陣列會採用插入排序,這會導致對陣列進行的亂序並不是真正的亂序,即使最新的版本 chrome 採用了原地演算法使得排序變成了一個穩定的演算法,對於亂序的問題仍沒有解決
通過洗牌演算法可以達到真正的亂序,洗牌演算法分為原地和非原地,圖一是原地的洗牌演算法,不需要宣告額外的陣列從而更加節約記憶體佔用率,原理是依次遍歷陣列的元素,將當前元素和之後的所有元素中隨機選取一個,進行交換
25. 單例模式
通過 ES6 的 Proxy 攔截建構函式的執行方法來實現的單例模式
26. promisify
使用方法:
promisify 函式是將回撥函式變為 promise 的輔助函式,適合 error-first 風格(nodejs)的回撥函式,原理是給 error-first 風格的回撥無論成功或者失敗,在執行完畢後都會執行最後一個回撥函式,我們需要做的就是讓這個回撥函式控制 promise 的狀態即可
這裡還用了 Proxy 代理了整個 fs 模組,攔截 get 方法,使得不需要手動給 fs 模組所有的方法都包裹一層 promisify 函式,更加的靈活
27. 優雅的處理 async/await
使用方法:
無需每次使用 async/await 都包裹一層 try/catch ,更加的優雅,這裡提供另外一個思路,如果使用了 webpack 可以編寫一個 loader,分析 AST 語法樹,遇到 await 語法,自動注入 try/catch,這樣連輔助函式都不需要使用
28. 釋出訂閱 EventEmitter
通過 on 方法註冊事件,trigger 方法觸發事件,來達到事件之間的鬆散解耦,並且額外新增了 once 和 off 輔助函式用於註冊只觸發一次的事件以及登出事件
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2647205/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一個合格的Web前端工程師要掌握的知識點彙總!Web前端工程師
- 一名合格的前端開發工程師應該掌握的8個技能前端工程師
- 運維工程師要掌握的內容運維工程師
- 一名【合格】前端工程師的自檢清單前端工程師
- 前端工程師必須掌握的設計模式前端工程師設計模式
- 成為一名合格的Java工程師,需要掌握哪些基本知識Java工程師
- 寫給前端工程師看的Docker教程-中級篇前端工程師Docker
- 一個合格的web前端程式設計師要學會哪些技能?Web前端程式設計師
- 作為一名合格的前端開發工程師需要會哪些前端工程師
- php各級工程師需要掌握的知識體系PHP工程師
- 《一名【合格】前端工程師的自檢清單》答案參考(一)前端工程師
- 前端工程師分享幾個CSS技巧前端工程師CSS
- 掌握11項技能,你就是優秀的前端開發工程師前端工程師
- 前端修煉の道 | 如何成為一名合格前端開發工程師?前端工程師
- 想要成為Java工程師,你要熟練掌握MySQLJava工程師MySql
- 中級工程師之路工程師
- 一名合格的運維工程師的歷練之路運維工程師
- 優秀前端開發工程師必須掌握的七大技能前端工程師
- 受大廠們青睞的Web前端工程師需要掌握的3項能力!Web前端工程師
- JavaScript必須要掌握的知識-作用域JavaScript
- 前端裝逼技巧 108 式(三)—— 冇得感情的API呼叫工程師前端API工程師
- 前端工程師的進階之路前端工程師
- 中級 Java 軟體工程師會遇到的事情Java軟體工程工程師
- 運維工程師需要掌握的7大武器運維工程師
- 好程式設計師Web前端分享無法忽視的JavaScript技巧程式設計師Web前端JavaScript
- 各類初、中、高階工程師職稱 要的滴滴工程師
- 如何能進階成為一個合格的測試工程師工程師
- 學習web前端,必須要掌握的CSS原理Web前端CSS
- 5分鐘掌握JavaScript小技巧JavaScript
- 前端工程師必備:前端的模組化前端工程師
- 合格前端系列第六彈-從指向看JavaScript前端JavaScript
- 前端工程師的未來在哪裡?前端工程師
- 寫給前端工程師的 Flutter 教程前端工程師Flutter
- 大資料工程師需要掌握的知識點大資料工程師
- 怎樣才算合格的運維工程師?linux運維技術運維工程師Linux
- Java招聘門檻提高,怎樣才能成為合格的Java工程師?Java工程師
- 乾貨 | AI 工程師必讀,從實踐的角度解析一名合格的AI工程師是怎樣煉成的AI工程師
- 前端20個靈魂拷問 徹底搞明白你就是中級前端工程師 【下篇】前端工程師