天天看點

聊聊Lodash聊聊Lodash

聊聊Lodash

如果說要推薦工具庫給JavaScript新手,第一個我會選擇Lodash,為什麼推薦這個看似可有可無的工具庫呢?因為我覺得Lodash可以傳達一種程式設計理念,通過高層抽象概念使寫出來的代碼更加優雅簡潔。

高層抽象概念

請讀者先閱讀下面一小段代碼,留意自己了解代碼所花費的時間,代碼如下:

let numbers = [, , , , , ];
let targets = [];

for(var i = ; i < numbers.length; i++) {
    if (numbers[i] %  === ) {
        targets.push(numbers[i]);
    }
}
           

了解上面這段代碼的含義,對所有程式員都不是問題,即從一個數組中挑出所有偶數,具體過程大緻如下:

  • 有一個數字數組與目标數組
  • 循環周遊數字數組
  • 如果是偶數将其放到目标數組中

不同讀者了解代碼花費的時間有所差異,可能是5秒、10秒不等,但不管每個人是多長時間,問大家一個問題:“這段代碼在可讀性方面是否還有優化空間?”。

代碼可讀性之是以重要,是因為重要代碼被閱讀的時間遠大于編寫所花費的時間,可讀性越好,維護成本也就更低,出錯機率相應更小。回到上面的問題:“如何優化?”,我的答案是使用filter方法:

const _ = require('lodash');

let numbers = [, , , , , ];
let targets = _.filter(numbers, item => item %  === );

// Array.prototype.filter可以達到同樣效果
           

如果對filter不熟悉,了解這段代碼可能花費比之前代碼更長的時間,但這是因為其中包含學習filter所花費的時間。如果熟悉filter概念,這段代碼了解起來一定比前者所花費時間更短。

了解後者比前者更快的原因在于後者的程式語句包含更高層級的抽象概念,而這個概念在你閱讀代碼前就知道,是以你能更快了解這一小段代碼的具體含義。而如果代碼未出現filter概念,每次我們都需要從更基礎的概念中總結出一個filter的概念,這個過程随着次數增加會變得越發熟練,但這個過程永遠存在。(想象一下出現

10

的地方都寫成

5 + 5

)。

Lodash

介紹Lodash,還是從代碼開始:

let list = [{name: 'x', age: }, {name: 'y', age: }...];

// begin
let res = {};
for(var i = ; i < list.length - ; i++) {
    if (!res[list[i].age]) {
        res[list[i].age] = [];
    }

    res[list[i].age].push(list[i]);
}
// end

// begin
let names = [];
for(var i = ; i < list.length - ; i++) {
    if (names.indexOf(list[i].name) === -) {
        names.push(list[i].name);
    }
}
// end
           

兩個begin-end注釋之間的代碼分别做了什麼?是不是比最開始的例子更難了解?第一部分是将list按age分組,獲得了一個age為key的對象,每個key對應的值都是同年齡人數組,第二部分則是将list中所有不重複的name挑出來作為一個數組。

使用Lodash改寫上述代碼:

const _ = require('lodash');
let list = [{name: 'x', age: }, {name: 'y', age: }...];


let res = _.groupBy(list, 'age');

let names = _.uniq(_.map(list, 'name'));
           

改寫後代碼變得更簡潔,但最重要的是代碼自身傳達了更高層面的抽象概念,讓我們可以更快了解代碼,簡潔隻是附帶優點。

Lodash中的大部分方法都是根據經驗将常見代碼邏輯總結為一個抽象概念供大家使用,學習并了解其所傳達的概念是沒有語言邊界的,意思是你學到的大部分方法、概念在其他語言中應當都有相對應的替代物。Lodash中的常用方法很多,在此不做過多講述,大家從文檔中學習吧。

如果你在寫代碼的過程中總感覺有些邏輯重複又重複,也許是時候試試Lodash了。

常用方法:

_.each、_.map、_.pick、_.orderBy、_.groupBy、_.isEmpty、_.filter、_.find、_.padStart、_.omit、_.assign…

部落格原文