一秃嗜、講在前:
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"]