lodash用法詳解以及與ES6的對比

一秃嗜、講在前:

1储玫、版本:VERSION = 4.17.5;
2、中文文檔:https://www.lodashjs.com/驯镊;
3葫督、安裝引入:

<script src="lodash.js"></script>

通過 npm:

$ npm i -g npm
$ npm i --save lodash

import _ from 'lodash';

二、功能簡介

  • Array板惑,適用于數(shù)組類型橄镜,比如填充數(shù)據(jù)、查找元素冯乘、數(shù)組分片等操作
  • Collection洽胶,適用于數(shù)組和對象類型,部分適用于字符串裆馒,比如分組姊氓、查找、過濾等操作
  • Function喷好,適用于函數(shù)類型翔横,比如節(jié)流、延遲梗搅、緩存禾唁、設(shè)置鉤子等操作
  • Lang,普遍適用于各種類型些膨,常用于執(zhí)行類型判斷和類型轉(zhuǎn)換
  • Math蟀俊,適用于數(shù)值類型,常用于執(zhí)行數(shù)學(xué)運算
  • Number订雾,適用于生成隨機數(shù)肢预,比較數(shù)值與數(shù)值區(qū)間的關(guān)系
  • Object,適用于對象類型洼哎,常用于對象的創(chuàng)建烫映、擴展、類型轉(zhuǎn)換噩峦、檢索锭沟、集合等操作
  • Seq,常用于創(chuàng)建鏈式調(diào)用识补,提高執(zhí)行性能(惰性計算)
  • String族淮,適用于字符串類型

lodash/fp 模塊提供了更接近函數(shù)式編程的開發(fā)方式,其內(nèi)部的函數(shù)經(jīng)過包裝,具有 immutable祝辣、auto-curried贴妻、iteratee-first、data-last(官方介紹)等特點蝙斜。Lodash 在 GitHub Wiki 中對 lodash/fp 的特點做了如下概述:

  • Fixed Arity名惩,固化參數(shù)個數(shù),便于柯里化
  • Rearragned Arguments孕荠,重新調(diào)整參數(shù)位置娩鹉,便于函數(shù)之間的聚合
  • Capped Iteratee Argument,封裝 Iteratee 參數(shù)
  • New Methods

三稚伍、基本使用對比原生js

1. N 次循環(huán)

// 1\. Basic for loop.
for(var i = 0; i < 5; i++) {
    // ...
}

// 2\. Using Array's join and split methods
Array.apply(null, Array(5)).forEach(function(){
    // ...
});

// Lodash
_.times(5, function(){
    // ...
});

for 語句是執(zhí)行循環(huán)的不二選擇弯予,Array.apply 也可以模擬循環(huán),但在上面代碼的使用場景下个曙,_.times() 的解決方式更加簡潔和易于理解熙涤。

2. 深層查找屬性值

// Fetch the name of the first pet from each owner
var ownerArr = [{
    "owner": "Colin",
    "pets": [{"name":"dog1"}, {"name": "dog2"}]
}, {
    "owner": "John",
    "pets": [{"name":"dog3"}, {"name": "dog4"}]
}];

// Array's map method.
ownerArr.map(function(owner){
   return owner.pets[0].name;
});

// Lodash
_.map(ownerArr, 'pets[0].name');

_.map 方法是對原生 map 方法的改進,其中使用 pets[0].name 字符串對嵌套數(shù)據(jù)取值的方式簡化了很多冗余的代碼困檩,非常類似使用 jQuery 選擇 DOM 節(jié)點 ul > li > a,對于前端開發(fā)者來說有種久違的親切感那槽。

3. 個性化數(shù)組

// Array's map method.
Array.apply(null, Array(6)).map(function(item, index){
    return "ball_" + index;
});

// Lodash
_.times(6, _.uniqueId.bind(null, 'ball_'));

// Lodash
_.times(6, _.partial(_.uniqueId, 'ball_'));
// eg. [ball_0, ball_1, ball_2, ball_3, ball_4, ball_5]

在上面的代碼中悼沿,我們要創(chuàng)建一個初始值不同、長度為 6 的數(shù)組骚灸,其中 _.uniqueId 方法用于生成獨一無二的標識符(遞增的數(shù)字糟趾,在程序運行期間保持獨一無二),_partial 方法是對 bind 的封裝甚牲。

4. 深拷貝

var objA = {
    "name": "colin"
}

// Normal method? Too long. See Stackoverflow for solution:
// http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript

// Lodash
var objB = _.cloneDeep(objA);
objB === objA // false

JavaScript 沒有直接提供深拷貝的函數(shù)义郑,但我們可以用其他函數(shù)來模擬,比如 JSON.parse(JSON.stringify(objectToClone))丈钙,但這種方法要求對象中的屬性值不能是函數(shù)非驮。Lodash 中的 _.cloneDeep 函數(shù)封裝了深拷貝的邏輯,用起來更加簡潔雏赦。

5. 隨機數(shù)

// Naive utility method
function getRandomNumber(min, max){
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

getRandomNumber(15, 20);

// Lodash
_.random(15, 20);

Lodash 的隨機數(shù)生成函數(shù)更貼近實際開發(fā)劫笙,ECMAScript 的隨機數(shù)生成函數(shù)是底層必備的接口,兩者都不可或缺星岗。此外填大,使用 _.random(15, 20, true) 還可以在 15 到 20 之間生成隨機的浮點數(shù)。

6. 對象擴展

// Adding extend function to Object.prototype
Object.prototype.extend = function(obj) {
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            this[i] = obj[i];
        }
    }
};

var objA = {"name": "colin", "car": "suzuki"};
var objB = {"name": "james", "age": 17};

objA.extend(objB);
objA; // {"name": "james", "age": 17, "car": "suzuki"};

// Lodash
_.assign(objA, objB);

_.assign 是淺拷貝俏橘,和 ES6 新增的 Ojbect.assign 函數(shù)功能一致(建議優(yōu)先使用 Object.assign)允华。

7. 篩選屬性

// Naive method: Remove an array of keys from object
Object.prototype.remove = function(arr) {
    var that = this;
    arr.forEach(function(key){
        delete(that[key]);
    });
};

var objA = {"name": "colin", "car": "suzuki", "age": 17};

objA.remove(['car', 'age']);
objA; // {"name": "colin"}

// Lodash
objA = _.omit(objA, ['car', 'age']);
// => {"name": "colin"}
objA = _.omit(objA, 'car');
// => {"name": "colin", "age": 17};
objA = _.omit(objA, _.isNumber);
// => {"name": "colin"};

大多數(shù)情況下,Lodash 所提供的輔助函數(shù)都會比原生的函數(shù)更貼近開發(fā)需求。在上面的代碼中靴寂,開發(fā)者可以使用數(shù)組磷蜀、字符串以及函數(shù)的方式篩選對象的屬性,并且最終會返回一個新的對象榨汤,中間執(zhí)行篩選時不會對舊對象產(chǎn)生影響蠕搜。

// Naive method: Returning a new object with selected properties
Object.prototype.pick = function(arr) {
    var _this = this;
    var obj = {};
    arr.forEach(function(key){
        obj[key] = _this[key];
    });

    return obj;
};

var objA = {"name": "colin", "car": "suzuki", "age": 17};

var objB = objA.pick(['car', 'age']);
// {"car": "suzuki", "age": 17}

// Lodash
var objB = _.pick(objA, ['car', 'age']);
// {"car": "suzuki", "age": 17}

_.pick_.omit 的相反操作,用于從其他對象中挑選屬性生成新的對象收壕。

8. 隨機元素

var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"];

function pickRandomPerson(luckyDraw){
    var index = Math.floor(Math.random() * (luckyDraw.length -1));
    return luckyDraw[index];
}

pickRandomPerson(luckyDraw); // John

// Lodash
_.sample(luckyDraw); // Colin

// Lodash - Getting 2 random item
_.sample(luckyDraw, 2); // ['John','Lily']

_.sample 支持隨機挑選多個元素并返回心的數(shù)組妓灌。

9. 針對 JSON.parse 的錯誤處理

// Using try-catch to handle the JSON.parse error
function parse(str){
    try {
        return JSON.parse(str);
    }

    catch(e) {
        return false;
    }
}

// With Lodash
function parseLodash(str){
    return _.attempt(JSON.parse.bind(null, str));
}

parse('a');
// => false
parseLodash('a');
// => Return an error object

parse('{"name": "colin"}');
// => Return {"name": "colin"}
parseLodash('{"name": "colin"}');
// => Return {"name": "colin"}

如果你在使用 JSON.parse 時沒有預(yù)置錯誤處理,那么它很有可能會成為一個定時炸彈蜜宪,我們不應(yīng)該默認接收的 JSON 對象都是有效的虫埂。try-catch 是最常見的錯誤處理方式,如果項目中 Lodash圃验,那么可以使用 _.attmpt 替代 try-catch 的方式掉伏,當解析 JSON 出錯時,該方法會返回一個 Error 對象澳窑。

隨著 ES6 的普及斧散,Lodash 的功能或多或少會被原生功能所替代,所以使用時還需要進一步甄別摊聋,建議優(yōu)先使用原生函數(shù)鸡捐,有關(guān) ES6 替代 Lodash 的部分,請參考文章《10 Lodash Features You Can Replace with ES6》(中文版《10 個可用 ES6 替代的 Lodash 特性》)麻裁。

其中有兩處非常值得一看:

// 使用箭頭函數(shù)創(chuàng)建可復(fù)用的路徑
const object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

[
    obj => obj.a[0].b.c,
    obj => obj.a[1]
].map(path => path(object));

// 使用箭頭函數(shù)編寫鏈式調(diào)用
const pipe = functions => data => {
    return functions.reduce(
        (value, func) => func(value),
        data
    );
};

const pipeline = pipe([
    x => x * 2,
    x => x / 3,
    x => x > 5,
    b => !b
]);

pipeline(5);
// true
pipeline(20);
// false

在 ES6 中箍镜,如果一個函數(shù)只接收一個形參且函數(shù)體是一個 return 語句,就可以使用箭頭函數(shù)簡化為:

const func = p => v;

// 類似于(不完全相同)
const func = function (p) {
    return v;
}

當有多重嵌套時煎源,可以簡化為:

const func = a => b => c => a + b + c;
func(1)(2)(3);
// => 6

// 類似于
const func = function (a) {
    return function (b) {
        return function (e) {
            return a + b + c;
        }
    }
}

四色迂、10 個可用 ES6 替代的 Lodash 特性

原文鏈接: www.sitepoint.com

中文:https://www.zcfy.cc/article/10-lodash-features-you-can-replace-with-es6-467.html

現(xiàn)在ES6 確實已經(jīng)大行其道了,但是 lodash 仍然有不可取代的地方手销。對我而言主要是兩點:
1歇僧、lodash 的操作(例如 forEach)都是對對象數(shù)組都可用的,而 ES6 原生方法往往只對數(shù)組有效锋拖。
2馏慨、lodash 的所有操作都是 null-safe 的,而 ES6 完全不考慮姑隅。結(jié)果就變成了

const obj={a: {b: {c: {one: 'blue', two: 'red'}}}}
_.map(_.get(obj, 'a.b.c'), (item, key)=> item)   // ["blue", "red"]

這樣的代碼想用原生 ES6 實現(xiàn)写隶,就變得繁瑣了很多

const obj={a: {b: {c: {one: 'blue', two: 'red'}}}}
let tmp = obj && obj.a && obj.a.b && obj.a.b.c
tmp && Object.keys(tmp).map(key => tmp[key])  // / ["blue", "red"]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市讲仰,隨后出現(xiàn)的幾起案子慕趴,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冕房,死亡現(xiàn)場離奇詭異躏啰,居然都是意外死亡,警方通過查閱死者的電腦和手機耙册,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門给僵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人详拙,你說我怎么就攤上這事帝际。” “怎么了饶辙?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵蹲诀,是天一觀的道長。 經(jīng)常有香客問我弃揽,道長脯爪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任矿微,我火速辦了婚禮痕慢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涌矢。我一直安慰自己守屉,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布蒿辙。 她就那樣靜靜地躺著,像睡著了一般滨巴。 火紅的嫁衣襯著肌膚如雪思灌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天恭取,我揣著相機與錄音泰偿,去河邊找鬼。 笑死蜈垮,一個胖子當著我的面吹牛耗跛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播攒发,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼调塌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惠猿?” 一聲冷哼從身側(cè)響起羔砾,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后姜凄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體政溃,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年态秧,在試婚紗的時候發(fā)現(xiàn)自己被綠了董虱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡申鱼,死狀恐怖愤诱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情润讥,我是刑警寧澤转锈,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站楚殿,受9級特大地震影響撮慨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脆粥,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一砌溺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧变隔,春花似錦规伐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肌厨,卻和暖如春培慌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柑爸。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工吵护, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人表鳍。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓馅而,卻偏偏與公主長得像,于是被迫代替她去往敵國和親譬圣。 傳聞我的和親對象是個殘疾皇子瓮恭,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標準厘熟。 注意:講述HT...
    kismetajun閱讀 27,474評論 1 45
  • 函數(shù)和對象 1偎血、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念诸衔。通過函數(shù)可以封裝任意多條語句,而且...
    道無虛閱讀 4,556評論 0 5
  • 早晨7:30,老公將我送到辦公樓下帖渠,掉轉(zhuǎn)車頭上了高速谒亦。 今天他要去170公里外的另外一座城市講課。14:30開始講...
    對花情味閱讀 692評論 4 4
  • 有一段時間空郊,夜晚睡不著份招,關(guān)了燈,站在窗戶邊狞甚,觀察這個小區(qū)锁摔。 夜歸的女生,進了房間哼审、立刻洗澡谐腰,然后睡覺...
    天小下閱讀 458評論 1 6
  • 是的,好久沒感謝自己了涩盾。感謝一下吧~ 親愛滴wj你是最棒的:你那么善良十气,是發(fā)自內(nèi)心的善良。雖然現(xiàn)在的社會春霍,你的這種...