Lodash

一、Lodash是什麼?

Lodash是一個一致性、模塊化、高性能的 JavaScript 實用工具庫。它內部封裝了諸多對字符串、數組、對象等常見數據類型的處理函數,javascript

其中部分是目前ECMAScript還沒有制訂的規範,但同時被業界所承認的輔助函數。css

二、爲何會出現Lodash?

任何一個庫和框架的出現都是爲了解決問題的,那麼Lodash是解決什麼問題的?html

官方文檔上的定義:java

Lodash 經過下降 array、number、objects、string 等等的使用難度從而讓 JavaScript 變得更簡單。 Lodash 的模塊化方法 很是適用於:git

  • 遍歷 array、object 和 string
  • 對值進行操做和檢測
  • 建立符合功能的函數

Lodash就是這樣的一個工具庫,方便咱們在平常的開發中對數據的操做,特別是數組和對象的各類讀寫等操做,好比去重,拷貝,合併,過濾,求交集,求和等等,提升開發效率。github

三、Lodash可用性怎麼樣?

天天使用npm安裝Lodash的數量在百萬級以上,這在必定程度上證實了其代碼的健壯性。npm

在github上的數據也證實了這一點:編程

Core build (~4 kB gzipped) Full build (~24 kB gzipped)redux

完整版導出min版本的話大概78k,建議用的時候要根據場景按需引入 或者打包的時候不要打包進bundle裏api

四、Lodash怎麼用?有什麼特色?

(1) 安裝

Lodash地址

(2) 使用

api文檔 使用範例

(3) 功能簡介(版本4.17)

  • Array,適用於數組類型,好比增刪改查、填充數據(_.fill)、查找元素(_.findeIndex)、數組分片(_.chunk)等操做
  • Collection,適用於數組和對象類型,部分適用於字符串,好比遍歷、分組、查找、過濾等操做
  • Function,適用於函數類型,好比節流、延遲、緩存、設置鉤子等操做
  • Lang,廣泛適用於各類類型,經常使用於執行類型判斷和類型轉換、深拷貝
  • Math,適用於數值類型,經常使用於執行數學運算(最大值、最小值求和)
  • Number,適用於生成隨機數,比較數值與數值區間的關係
  • Object,適用於對象類型,經常使用於對象的建立、擴展、類型轉換、檢索、集合等操做
  • Seq,經常使用於建立鏈式調用,提升執行性能(惰性計算)
  • String,適用於字符串類型
  • Util,一些工具函數,好比_.attmpt 替代 try-catch 的方式,當解析 JSON 出錯時,該方法會返回一個Error對象
  • Properties, 模板方法 ES6的模板字符串和這個功能很像(對模板字符串進行了正則解析,將須要填入數據的位置預留出來,拼接成一個字符串)
  • Methods, 對lodash函數的引用

(4) 優點

一、函數式編程風格

經常使用核心概念純函數(註釋1)、柯里化函數、聲明式和命令式等

二、鏈式調用和惰性求值
//顯式調用
var users = [
  { 'user': 'barney',  'age': 36 },
  { 'user': 'fred',    'age': 40 },
  { 'user': 'pebbles', 'age': 1 }
];
 
var youngest = _
  .chain(users)    //能夠鏈式調用的關鍵 Returns the new lodash wrapper instance. 
  .sortBy('age')
  .map(function(o) {
    return o.user + ' is ' + o.age;
  })
  .head()
  .value();
// => 'pebbles is 1'
複製代碼
//隱式調用
var youngest = _(users)    // 不須要顯式的使用chain關鍵字
  .sortBy('age')
  .map(function(o) {
    return o.user + ' is ' + o.age;
  })
  .head()
複製代碼

注意二者的區別:

爲何要多出來一個 .value(),而不是直接出結果呢?那是由於可能要等待延時(Deferred execution)數據的到來,再執行取值。這就是咱們常說的Lazy evaluation (延遲計算/惰性求值)

(value)創建了一個隱式鏈對象,能夠把那些能操做並返回 arrays(數組)、collections(集合)、functions(函數)的」.Methods」(lodash的函數)串起來。 那些能返回「惟一值(single value)」或者可能返回原生數據類型(primitive value)會自動結束鏈式反應。 而顯式鏈則用.chain. 的方式實現延遲計算,即:求值操做等到 _value()被調用時再執行。

說到惰性求值官方這樣介紹的:

惰性求值(Lazy Evaluation),又譯爲惰性計算、懶惰求值,也稱爲傳需求調用(call-by-need),是計算機編程中的一個概念,它的目的是要最小化計算機要作的工做。 惰性求值中的參數直到須要時纔會進行計算。這種程序其實是從末尾開始反向執行的。它會判斷本身須要返回什麼,並繼續向後執行來肯定要這樣作須要哪些值。

How to Speed Up Lo-Dash ×100? Introducing Lazy Evaluation.中這個例子爲例

function priceLt(x) {
   return function(item) { return item.price > x; };
}
var gems = [
   { name: 'Sunstone', price: 4 }, { name: 'Amethyst', price: 15 },
   { name: 'Prehnite', price: 20}, { name: 'Sugilite', price: 7  },
   { name: 'Diopside', price: 3 }, { name: 'Feldspar', price: 13 },
   { name: 'Dioptase', price: 2 }, { name: 'Sapphire', price: 20 }
];
 
var chosen = _(gems).filter(priceLt(10)).take(3).value();
複製代碼

函數的目的是對數組gems進行篩選,選出3個price小於10的數據。

(1) 通常的作法(不用lodash)

var chosen = _(gems).filter(priceLt(10)).take(3) 先執行filter方法,遍歷gems數組(長度爲10),取出符合條件的數據:

[
   { name: 'Sunstone', price: 4 },
   { name: 'Sugilite', price: 7  },
   { name: 'Diopside', price: 3 },
   { name: 'Dioptase', price: 2 }
]
複製代碼

而後,執行take方法,提取前3個數據。 總共遍歷的次數爲:10+3 執行的示例圖以下:

(2) 惰性求值作法

如下是實現的思路:

  1. _(gems)拿到數據集,緩存起來
  2. 遇到filter方法,先記下來
  3. 遇到take方法,先記下來
  4. 遇到value方法,說明時機到了
  5. 把小本本拿出來,看下要求:要取出3個數,price<10
  6. 使用filter方法裏的判斷方法priceLt對數據進行逐個裁決

一共只執行了5次,就把結果拿到

83f1785331176561cb98c745da91fe22.gif
惰性計算的特色:
一、 延遲計算,把要作的計算先緩存,不執行
二、 數據管道,逐個數據經過「裁決」方法,在這個相似安檢的過程當中,進行過關的操做,最後只留下符合要求的數據
三、 觸發時機,方法緩存,那麼就須要一個方法來觸發執行。lodash就是使用value方法,通知真正開始計算

五、爲何不用ES6徹底替換Lodash?

目前替換不了,就對null值容錯方面上講,Lodash有着更好的性能 好比咱們想從一組對象中摘取出某個屬性的值

let arr = [{ n: 1 }, { n: 2 }]
// ES6
arr.map(obj => obj.n)
// Lodash
_.map(arr, 'n')
複製代碼

當對象類型的嵌套層級不少時:

let arr = [
 { a:[{ n:1 }]},
 { b:[{ n:1 }]}
]
// ES6
arr.map(obj => obj.a[0].n) 
// TypeError: 屬性 'a' 在 arr[1] 中未定義
// Lodash
_.map(arr, 'a[0].n') 
// => [1, undefined]
複製代碼

許多 Lodash 提供的功能已經能夠用 ES6 來替換,有些Lodash方法,ES6是沒有的。Lodash 這樣的類庫也在不斷推進 JavaScript 語言自己的發展

資料

Lodash git地址 Lodash中文文檔 顯試調用與隱性調用

註釋1:純函數:對於相同的輸入,永遠會獲得相同的輸出,並且沒有任何可觀察的反作用,也不依賴外部環境的狀態的函數,好比redux中reducer。

相關文章
相關標籤/搜索