如何實現 lodash.get 函數及可選鏈操做簡化取值

本篇文章簡介 lodash.get 函數的實現以及可替代的可選鏈操做,源於我本身的倉庫 面試每日一題,其中記錄了關於前端進階及工程化的各類問題。心靈雞湯之因此被抵制就是由於只有雞湯沒有勺子,別人也開始問個人倉庫有沒有答案了。所以我將寫一大堆文章來捎帶回答這些問題 ---- 若是有時間的話。javascript

最近整理了個人 github 中的博客,山月的博客 歡迎訂閱前端


lodash 基本上成爲了 js 項目的標配工具函數,普遍應用在各類服務端以及前端應用中,可是它的包體積略大了一些。對於服務端來講,包的體積並非十分的重要,或者換句話說,不像前端那樣對包的體積特別敏感,一分一毫都會影響頁面打開的性能,從而影響用戶體驗。java

正由於前端打包體積對於用戶體驗的重要性,所以有各類各樣減少包體積的方法。針對 lodash 來講,你徹底沒必要要引入 lodash 的全部工具函數,你只須要按需引入或者直接使用單函數包。關於按需引入你能夠參考如下文章:git

Lessons on tree-shaking Lodash with Webpack and Babel

另外一方面,隨着 ES6+ 的發展,以及瀏覽器與 Node 對 ES 標準的支持加強,不少 lodash 的函數都很容易實現或者說已被 ES6+ 實現。如 _.assign_.trim_.startsWith 等等已被 ES6+ 實現,而 _.uniq 又很容易經過 new Set() 來解決。github

有人就在 github 上總結了 you-dont-need/You-Dont-Need-Lodash-Underscore,其中囊括了不少工具函數很簡易的實現。面試

<!--more-->redis

根據山月浸淫 JS 項目的多年經驗,使用 lodash 的大多數場景都是在 lodash.get,其頻繁程度就比如 redis 界的 set/get。那爲何 lodash.get 會使用如此頻繁呢,這要從它解決什麼問題開始。segmentfault

lodash.get 解決什麼問題

如上所示,當咱們沒法正確獲取數據時將會報錯,那若是咱們想要避免錯誤的發生呢?那隻能寫一條很長很長的判斷了前端工程化

在 js 中常常會出現嵌套調用這種狀況,如 a.b.c.d.e,可是這麼寫很容易拋出異常。你須要這麼寫 a && a.b && a.b.c && a.b.c.d && a.b.c.d.e,可是顯得有些囉嗦與冗長了。特別是在 graphql 中,這種嵌套調用更是難以免。數組

const o = {}

o && o.a && o.a.b && o.a.b.c && o.a.b.c.d

恩,光是想想每次取數據都要這麼長就很難受...

lodash.get 就是解決這個問題的,這時就須要一個 get 函數,使用 get(a, 'b.c.d.e') 簡單清晰,而且容錯性提升了不少。

_.get(o, 'a.b.c.d.e')

如何實現 lodash.get

get(object: object, path: [never]): never

實現 lodash.get 的函數功能以前,先標明它的測試用例。它除了能夠應用在嵌套對象上,還能夠應用在嵌套數組中:

get({ a: null }, 'a.b.c', 3)
// output: 3

get({ a: undefined }, 'a', 3)
// output: 3

get({ a: null }, 'a', 3)
// output: 3

get({ a: [{ b: 1 }]}, 'a[0].b', 3)
// output: 1

path 中也多是數組的路徑,所有轉化成 . 運算符並組成數組

// a[3].b -> a.3.b
const paths = path.replace(/\[(\d+)\]/g, '.$1').split('.')

而後層層迭代屬性便可,另外注意 nullundefined 取屬性會報錯,因此使用 Object 包裝一下。

function get (source, path, defaultValue = undefined) {
  // a[3].b -> a.3.b
  const paths = path.replace(/\[(\d+)\]/g, '.$1').split('.')
  let result = source
  for (const p of paths) {
    result = Object(result)[p]
    if (result === undefined) {
      return defaultValue
    }
  }
  return result
}

You Dont Need Lodash: 可選鏈

const o = {}

o && o.a && o.a.b && o.a.b.c && o.a.b.c.d

可選鏈,(optional chaining),操做符表示爲 ?.,屬於 ES2020 新增的內容,另外在 Typescript 3.7 中也添加了可選鏈的操做,大大簡化了對象的訪問。經過獲取對象屬性得到的值多是undefined或null時,可選鏈操做符提供了一種方法來簡化被鏈接對象的值訪問。

const o = {}

o?.a?.b?.c?.d

當引入可選鏈以後,_.get 就不是很必要了

我是山月,能夠加我微信 shanyue94 與我交流,備註交流。另外能夠關注個人公衆號【全棧成長之路】

若是你對全棧面試,前端工程化,graphql,devops,我的服務器運維以及微服務感興趣的話,能夠關注我

相關文章
相關標籤/搜索