合格的中級前端工程師要掌握的 JavaScript 技巧

智雲程式設計發表於2019-06-10

1.判斷物件的資料型別

合格的中級前端工程師要掌握的 JavaScript 技巧

使用 Object.prototype.toString 配合閉包,透過傳入不同的判斷型別來返回不同的判斷函式,一行程式碼,簡潔優雅靈活(注意傳入 type 引數時首字母大寫)

不推薦將這個函式用來檢測可能會產生包裝型別的基本資料型別上,因為 call 會將第一個引數進行裝箱操作

2. ES5 實現陣列 map 方法

image
image

值得一提的是,map 的第二個引數為第一個引數回撥中的 this 指向,如果第一個引數為箭頭函式,那設定第二個 this 會因為箭頭函式的詞法繫結而失效

另外就是對稀疏陣列的處理,透過 hasOwnProperty 來判斷當前下標的元素是否存在與陣列中(感謝評論區的朋友)

3. 使用 reduce 實現陣列 map 方法

image
image

4. ES5 實現陣列 filter 方法

image
image

5. 使用 reduce 實現陣列 filter 方法

image
image

6. ES5 實現陣列的 some 方法

image
image

執行 some 方法的陣列如果是一個空陣列,最終始終會返回  false ,而另一個陣列的 every 方法中的陣列如果是一個空陣列,會始終返回  true

如果你對前端開發這門技術感興趣,這裡推薦一下我的前端學習交流群: 767273102 ,裡面都是學習前端的從最基礎的HTML+CSS+JavaScript。jQuery,Ajax,node,angular等到移動端HTML5的專案實戰的資料都有整理,送給每一位前端小夥伴。最新技術,與企業需求同步。好友都在裡面學習交流,每天都會有大牛定時講解前端技術!

7. ES5 實現陣列的 reduce 方法

image
image

因為可能存在稀疏陣列的關係,所以 reduce 實現略有點複雜,需要保證跳過稀疏元素,遍歷正確的元素和下標,有更簡潔的寫法歡迎評論區留言

8. 使用 reduce 實現陣列的 flat 方法

image
image

因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會預設指向 window 從而發生錯誤

原理透過 reduce 遍歷陣列,遇到陣列的某個元素仍是陣列時,透過 ES6 的擴充套件運算子對其進行降維(ES5 可以使用 concat 方法),而這個陣列元素可能內部還巢狀陣列,所以需要遞迴呼叫 selfFlat

同時原生的 flat 方法支援一個 depth 參數列示降維的深度,預設為 1 即給陣列降一層維度

image
image

傳入 Inifity 會將傳入的陣列變成一個一維陣列

image
image

原理是每遞迴一次將 depth 引數減 1,如果 depth 引數為 0 時,直接返回原陣列

9. 實現 ES6 的 class 語法

image
image

ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,透過 Object.create 方法創造一個空物件,並將這個空物件繼承 Object.create 方法的引數,再讓子類(subType)的原型物件等於這個空物件,就可以實現子類例項的原型等於這個空物件,而這個空物件的原型又等於父類原型物件(superType.prototype)的繼承關係

而 Object.create 支援第二個引數,即給生成的空物件定義屬性和屬性描述符/訪問器描述符,我們可以給這個空物件定義一個 constructor 屬性更加符合預設的繼承行為,同時它是不可列舉的內部屬性(enumerable:false)

而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到例項與例項之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設定為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性

10. 函式柯里化

image
image

使用方法:

image
image

柯里化是函數語言程式設計的一個重要技巧,將使用多個引數的一個函式轉換成一系列使用一個引數的函式的技術

函數語言程式設計另一個重要的函式 compose,能夠將函式進行組合,而組合的函式只接受一個引數,所以如果有接受多個函式的需求並且需要用到 compose 進行函式組合,就需要使用柯里化對準備組合的函式進行部分求值,讓它始終只接受一個引數

借用冴羽部落格中的一個例子

image
image

11. 函式柯里化(支援佔位符)

image
image

使用方法:

image
image

透過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的引數先去填充上一輪的佔位符,如果當前輪引數含有佔位符,則放到內部儲存的陣列末尾,當前輪的元素不會去填充當前輪引數的佔位符,只會填充之前傳入的佔位符

12. 偏函式

image
image

使用方法:

image
image

偏函式和柯里化概念類似,個人認為它們區別在於偏函式會固定你傳入的幾個引數,再一次性接受剩下的引數,而函式柯里化會根據你傳入引數不停的返回函式,直到引數個數滿足被柯里化前函式的引數個數

Function.prototype.bind 函式就是一個偏函式的典型代表,它接受的第二個引數開始,為預先新增到繫結函式的引數列表中的引數,與 bind 不同的是,上面的這個函式同樣支援佔位符

13. 斐波那契數列及其最佳化

image
image

利用函式記憶,將之前運算過的結果儲存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 物件會額外佔用記憶體

14. 實現函式 bind 方法

image
image

函式的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如

  • bind 返回的函式被 new 呼叫作為建構函式時,繫結的值會失效並且改為 new 指定的物件

  • 定義了繫結後函式的 length 屬性和 name 屬性(不可列舉屬性)

  • 繫結後函式的原型需指向原來的函式

15. 實現函式 call 方法

image
image

原理就是將函式作為傳入的上下文引數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 型別

16. 簡易的 CO 模組

image
image

使用方法:

image
image

run 函式接受一個生成器函式,每當 run 函式包裹的生成器函式遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動呼叫 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後列印所有解析的結果,衍變為現在用的最多的 async/await 語法

17. 函式防抖

image
image

leading 為是否在進入時立即執行一次, trailing 為是否在事件觸發結束後額外再觸發一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函式並重新設定一個新的定時器,直到超過規定時間自動觸發定時器中的函式

同時透過閉包向外暴露了一個 cancel 函式,使得外部能直接清除內部的計數器

18. 函式節流

image
image

和函式防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發

19. 圖片懶載入

image
image

getBoundClientRect 的實現方式,監聽 scroll 事件(建議給監聽事件新增節流),圖片載入完會從 img 標籤組成的 DOM 列表中刪除,最後所有的圖片載入完畢後需要解綁監聽事件

image
image

intersectionObserver 的實現方式,例項化一個 IntersectionObserver ,並使其觀察所有 img 標籤

當 img 標籤進入可視區域時會執行例項化時的回撥,同時給回撥傳入一個 entries 引數,儲存著例項觀察的所有元素的一些狀態,比如每個元素的邊界資訊,當前元素對應的 DOM 節點,當前元素進入可視區域的比率,每當一個元素進入可視區域,將真正的圖片賦值給當前 img 標籤,同時解除對其的觀察

20. new 關鍵字

image
image

21. 實現 Object.assign

image
image

Object.assign 的原理可以參考我另外一篇部落格

22. instanceof

image
image

原理是遞迴遍歷 right 引數的原型鏈,每次和 left 引數作比較,遍歷到原型鏈終點時則返回 false,找到則返回 true

23. 私有變數的實現

image
image

使用 Proxy 代理所有含有  _  開頭的變數,使其不可被外部訪問

image
image

透過閉包的形式儲存私有變數,缺點在於類的所有例項訪問的都是同一個私有變數

image
image

另一種閉包的實現,解決了上面那種閉包的缺點,每個例項都有各自的私有變數,缺點是捨棄了 class 語法的簡潔性,將所有的特權方法(訪問私有變數的方法)都儲存在建構函式中

image
image

透過 WeakMap 和閉包,在每次例項化時儲存當前例項和所有私有變數組成的物件,外部無法訪問閉包中的 WeakMap,使用 WeakMap 好處在於不需要擔心記憶體溢位的問題

24. 洗牌演算法

早前的 chrome 對於元素小於 10 的陣列會採用插入排序,這會導致對陣列進行的亂序並不是真正的亂序,即使最新的版本 chrome 採用了原地演算法使得排序變成了一個穩定的演算法,對於亂序的問題仍沒有解決

image
image
image
image

透過洗牌演算法可以達到真正的亂序,洗牌演算法分為原地和非原地,圖一是原地的洗牌演算法,不需要宣告額外的陣列從而更加節約記憶體佔用率,原理是依次遍歷陣列的元素,將當前元素和之後的所有元素中隨機選取一個,進行交換

25. 單例模式

image
image

透過 ES6 的 Proxy 攔截建構函式的執行方法來實現的單例模式

26. promisify

image
image

使用方法:

image
image

promisify 函式是將回撥函式變為 promise 的輔助函式,適合 error-first 風格(nodejs)的回撥函式,原理是給 error-first 風格的回撥無論成功或者失敗,在執行完畢後都會執行最後一個回撥函式,我們需要做的就是讓這個回撥函式控制 promise 的狀態即可

這裡還用了 Proxy 代理了整個 fs 模組,攔截 get 方法,使得不需要手動給 fs 模組所有的方法都包裹一層 promisify 函式,更加的靈活

27. 優雅的處理 async/await

image
image

使用方法:

image
image

無需每次使用 async/await 都包裹一層 try/catch ,更加的優雅,這裡提供另外一個思路,如果使用了 webpack 可以編寫一個 loader,分析 AST 語法樹,遇到 await 語法,自動注入 try/catch,這樣連輔助函式都不需要使用

28. 釋出訂閱 EventEmitter

image
image

透過 on 方法註冊事件,trigger 方法觸發事件,來達到事件之間的鬆散解耦,並且額外新增了 once 和 off 輔助函式用於註冊只觸發一次的事件以及登出事件


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2647205/,如需轉載,請註明出處,否則將追究法律責任。

相關文章