1. 簡介
- Lodash是一個一致性、模塊化、高性能的JavaScript實用庫。
- Lodash通過降低array、number、objects、string等等的使用難度從而讓JavaScript變得簡單。Lodash的模塊方法,非常適用于:
- 遍歷array、object 和 string
- 對值進行操作和檢測
- 創建符合功能的函數
1.1 安裝
- 瀏覽器環境:
<script src="lodash.js"></script>
- npm安裝:
npm i --save lodash
- Node.js環境中:
- // Load the full build.
var _ = require('lodash');
- // Load the core build.
var _ = require('lodash/core');
- // Load the FP build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');
- // Load method categories.
var array = require('lodash/array');
var object = require('lodash/fp/object');
- // Cherry-pick methods for smaller browserify/rollup/webpack bundles.
var at = require('lodash/at');
var curryN = require('lodash/fp/curryN');
- // Load the full build.
2. API介紹之數組
2.1 _.drop(array, [n=1])
- 創建一個切片數組,去除array前面的n個元素。(n默認為1)。返回array剩余切片。
2.1.1 API講解示例
_.drop([1, 2, 3]);
// => [2, 3]_.drop([1, 2, 3], 2);
// => [3]_.drop([1, 2, 3], 5);
// => []_.drop([1, 2, 3], 0);
// => [1, 2, 3]
2.1.2 業務場景:
行情部分本身后端會返回全部規格信息數組,但只要求展示兩個規格品類信息,若有三個及以上規格,默認展示除"通貨"外的前兩個需求。通貨默認在第一個,所以我們可以通過 _.drop(arr, 1)來實現。
webapp-hq中:
this.specs = res.result.spec.slice(1);
---To---
this.specs = _.drop(res.result.spec, 1);
2.1.3 相似API
_.dropRight(array, [n=1])
從末尾開始進行刪除_.dropWhile(array, [predicate=_.identity])
從頭開始刪除迭代器指定情形下的值,返回剩余值_.dropRightWhile(array, [predicate=_.identity])
同上功能,只不過從后面開始刪除
2.1.3 dropWhile對應業務場景 TODO:待補充
類似于filter,返回一堆數據,過濾出自己真正想要的數據,找個例子
2.2 _.head(array)
獲取數組array的第一個元素。
2.2.1 API講解示例
_.head([1, 2, 3]);
// => 1_.head([]);
// => undefined
2.2.2 業務場景
if (!this.specId || this.specId === 0 || this.specId === "0") {this.specId =this.specs &&this.specs.length &&this.specs[0] &&this.specs[0].id;console.log(this.specId, "自己獲取的");// this.specId = _.head(this.specs) && _.head(this.specs).id;// console.log(this.specId, "lodash獲取的");this.$emit("changeSpec", this.specId);
}
2.2.3 相似API
_.first
別名
2.3 _.take(array, [n=1])
創建一個數組切片,從array數組的起始元素開始提取n個元素。
2.3.1 API 講解示例
_.take([1, 2, 3]);
// => [1]_.take([1, 2, 3], 2);
// => [1, 2]_.take([1, 2, 3], 5);
// => [1, 2, 3]_.take([1, 2, 3], 0);
// => []
2.3.2 業務場景
- 當規格較多時,我們只想保留前幾條數據用于展示時,可以使用該API
- 我們可以先切掉頭部內容,之后再進行take提取
this.specs = _.take(_.drop(res.result.spec, 1));
- 若最后規格表示最新出現的,可以通過takeRight進行提取
2.3.3 相似API
_.takeRight(array, [n=1])
創建一個數組切片,從array數組的最后一個元素開始提取n個元素。_.takeRightWhile(array, [predicate=_.identity])
從array數組的最后一個元素開始提取元素,直到 predicate 返回假值。predicate 會傳入三個參數: (value, index, array)。_.takeWhile(array, [predicate=_.identity])
從array數組的起始元素開始提取元素,,直到 predicate 返回假值。predicate 會傳入三個參數: (value, index, array)。
3. API介紹之集合
3.1 _.filter(collection, [predicate=_.identity])
遍歷 collection(集合)元素,返回 predicate(斷言函數)返回真值 的所有元素的數組。 predicate(斷言函數)調用三個參數:(value, index|key, collection)。
3.1.1 API講解示例
var users = [{ 'user': 'barney', 'age': 36, 'active': true },{ 'user': 'fred', 'age': 40, 'active': false }
];_.filter(users, function(o) { return !o.active; });
// => objects for ['fred']// The `_.matches` iteratee shorthand.
_.filter(users, { 'age': 36, 'active': true });
// => objects for ['barney']// The `_.matchesProperty` iteratee shorthand.
_.filter(users, ['active', false]);
// => objects for ['fred']// The `_.property` iteratee shorthand.
_.filter(users, 'active');
// => objects for ['barney']
3.1.2 業務場景
當返回一個規格列表/任意對象列表,需要按照要求來過濾其中自己需要的數據,這時候需要用到_.filter進行過濾比較方便。
const testArr = [{id: 1,name: '二兩',isShow: true},{id: 2,name: '四兩',isShow: false},{id: 3,name: '六兩',isShow: true},{id: 4,name: '八兩',isShow: true},{id: 5,name: '十兩',isShow: false},]
const filterArr = testArr.filter((item) => item.isShow)const filterArr = _.filter(testArr, ['isShow', true])
const filterArr = _.filter(testArr, 'isShow')
3.2 _.find(collection, [predicate=_.identity], [fromIndex=0])
遍歷 collection(集合)元素,返回 predicate(斷言函數)第一個返回真值的第一個元素。predicate(斷言函數)調用3個參數: (value, index|key, collection)。
3.2.1 API講解示例
var users = [{ 'user': 'barney', 'age': 36, 'active': true },{ 'user': 'fred', 'age': 40, 'active': false },{ 'user': 'pebbles', 'age': 1, 'active': true }
];_.find(users, function(o) { return o.age < 40; });
// => object for 'barney'// The `_.matches` iteratee shorthand.
_.find(users, { 'age': 1, 'active': true });
// => object for 'pebbles'// The `_.matchesProperty` iteratee shorthand.
_.find(users, ['active', false]);
// => object for 'fred'// The `_.property` iteratee shorthand.
_.find(users, 'active');
// => object for 'barney'
3.2.2 業務場景
大講堂中,detail接口中返回了多個模塊的數據,以code為標識
此時,我們將數據分別提取出來進行使用。
歷史用法:
this.headerList =res.data.find((item) => {return item.code === "top_banner";
}).nodes || [];lodash用法:
this.headerList = _.find(res.data, ['code', 'top_banner']).nodes || []
3.2.3 相似API
_.findLast(collection, [predicate=_.identity], [fromIndex=collection.length-1])
類似于find,查到一個就停止,不同之處在于find是從左向右查找,findLast是從右向左查找。
3.3 _.sample(collection)
從collection(集合)中獲得一個隨機元素。
3.3.1 API講解示例
_.sample([1, 2, 3, 4]);
// => 2const arr = [{name: 'lihua',age: 12,},{name: 'xiaoming',age: 32,},{name: 'wang',age: 28,},];
_.sample(arr)
// => {name: 'lihua', age: 12}
3.3.2 業務場景
平臺專享處的輪播,會隨機選取姓氏進行處理,通過Math.random()方式,我們可以通過_.sample來進行改寫。
surnameArr 常見姓氏列表(取樣集合)const randomIdx = Math.floor(Math.random() * 43);
return surnameArr[randomIdx];return _.sample(surnameArr);
3.3.3 相似API
_.sampleSize(collection, [n=1])
從collection集合中隨機獲取n個元素
_.sampleSize([1, 2, 3], 2);
// => [3, 1]_.sampleSize([1, 2, 3], 4);
// => [2, 3, 1]
4. API介紹之Seq
5. API介紹之語言
5.1 _.eq(value, other)
執行SameValueZero 比較兩者的值,來確定它們是否相等。
5.1.1 API講解示例
var object = { 'a': 1 };
var other = { 'a': 1 };_.eq(object, object);
// => true_.eq(object, other);
// => false_.eq('a', 'a');
// => true_.eq('a', Object('a'));
// => false_.eq(NaN, NaN);
// => true
5.1.2 業務場景
當有需求需要判斷兩個值是否相等時,如:判斷當前是否是vip
!_.eq(this.customer_vip, 0);this.customer_vip !== 0;
5.1.3 相似API
_.gt(value, other)
檢查value是否大于other_.gte(value, other)
檢查value是夠大于等于other_.isEqual(value, other)
執行深比較來確定兩者的值是否相等。支持比較 arrays, array buffers, booleans, date objects, error objects, maps, numbers, Object objects, regexes, sets, strings, symbols, 以及 typed arrays. Object 對象值比較自身的屬性,不包括繼承的和可枚舉的屬性。 不支持函數和DOM節點比較。_.isEqualWith(value, other, [customizer])
這個方法類似_.isEqual。 除了它接受一個 customizer 用來定制比較值。_.lt(value, other)
檢查 value 是否小于 other。_.lte(value, other)
檢查 value 是否小于等于 other。
5.2 _.isEmpty(value)
檢查 value 是否為一個空對象,集合,映射或者set。 判斷的依據是除非是有枚舉屬性的對象,length 大于 0 的 arguments object, array, string 或類jquery選擇器。
5.2.1 API講解示例
_.isEmpty(null);
// => true_.isEmpty(true);
// => true_.isEmpty(1);
// => true_.isEmpty([1, 2, 3]);
// => false_.isEmpty({ 'a': 1 });
// => false
5.1.2 業務場景
我們經常為了兼容,獲取數組中第一個元素進行壓中或發送下一個網絡請求的操作,之前是要判斷這個數組是否存在,并且數組的length屬性。&&下來就會使整個判斷條件變得十分的長和復雜,此時,可以通過isEmpty來進行判斷。
this.trend_id =this.trendChartOptions &&this.trendChartOptions.length &&this.trendChartOptions[0] &&this.trendChartOptions[0].id;this.trendChartActive = this.trendChartOptions[0];-----this.trend_id =!_.isEmpty(this.trendChartOptions) &&this.trendChartOptions[0].id;
6. API介紹之對象
6.1 _.get(object, path, [defaultValue])
根據 object對象的path路徑獲取值。 如果解析 value 是 undefined 會以 defaultValue 取代。返回解析后的值。
6.1.1 API講解示例
var object = { 'a': [{ 'b': { 'c': 3 } }] };_.get(object, 'a[0].b.c');
// => 3_.get(object, ['a', '0', 'b', 'c']);
// => 3_.get(object, 'a.b.c', 'default');
// => 'default'
6.1.2 業務場景
在進行圖表數據存儲時對象進行存儲,key作為幾天的id,value則是這一天對應的數據。
const daysMap = {0: ['七', '天', '圖', '表', '數', '據'],3: ['三', '十', '天', '圖', '表', '數', '據'],6: ['六', '十', '天', '圖', '表', '數', '據'],}console.log(_.get(daysMap, 0, ['默', '認', '圖', '表', '數', '據']));
這樣,我們在點擊對應的activeOptions(七天、30天、60天)時,即可獲取當天對應的id,然后通過id就可以獲取到當天對應的數據。
6.1.3 相似API
-
_.result(object, path, [defaultValue])
這個方法類似_.get, 除了如果解析到的值是一個函數的話,就綁定 this 到這個函數并返回執行后的結果。 -
_.set(object, path, value)
設置 object對象中對應 path 屬性路徑上的值,如果path不存在,則創建。 缺少的索引屬性會創建為數組,而缺少的屬性會創建為對象。 使用_.setWith 定制path創建。 -
_.setWith(object, path, value, [customizer])
這個方法類似_.set,除了它接受一個 customizer,調用生成對象的 path。 如果 customizer 返回 undefined 將會有它的處理方法代替。 customizer 調用3個參數: (nsValue, key, nsObject)。
6.2 _.invoke(object, path, [args])
調用object對象path上的方法。
6.2.1 API講解示例
var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };_.invoke(object, 'a[0].b.c.slice', 1, 3);
// => [2, 3]
6.2.2 業務場景
之前有一次后端處理數據有誤,7天和30天請求時都返回了30天的數據,因為后期開發需要時間,所以需要前端暫時將返回的30天數據截取7天來進行使用,此時,我們就可以通過invoke進行截取。
const daysDataMap = {0: {trend: {price_list: [{tem: "1.01",time: "04-26",},{tem: "1.81",time: "04-27",},{tem: "2.01",time: "04-28",},{tem: "1.51",time: "04-29",},{tem: "0.91",time: "04-30",},{tem: "1.31",time: "05-01",},{tem: "1.11",time: "05-02",},]}}}console.log(_.invoke(daysDataMap, '0.trend.price_list.slice', 0, 3))
6.3 _.omitBy(object, [predicate=_.identity])
這個方法一個對象,這個對象忽略 predicate(斷言函數)判斷不是真值的屬性后,object自身和繼承的可枚舉屬性組成。predicate調用與2個參數:(value, key)。
6.3.1 API講解示例
var object = { 'a': 1, 'b': '2', 'c': 3 };_.omitBy(object, _.isNumber);
// => { 'b': '2' }
6.3.2 業務場景
過濾接口參數,若不同場景有的參數存在,則不必傳給后端。
let queryParams = {stateCode: options.stateCode,customerId: options.qrid,};之前過濾參數寫法:Object.entries(queryParams).forEach((f) => {if (!(f && f.length && f[1])) {delete queryParams[f[0]];}});console.log(queryParams, "之前方式過濾后的參數值");lodash 過濾參數寫法:const lodashRes = _.omitBy(queryParams, _.isEmpty);console.log(lodashRes, "lodash處理后的值");
6.3.3 相似API
_.omit(object, [props])
這個方法一個對象,這個對象由忽略屬性之外的object自身和繼承的可枚舉屬性組成。(注:可以理解為刪除object對象的屬性)。
var object = { 'a': 1, 'b': '2', 'c': 3 };_.omit(object, ['a', 'c']);
// => { 'b': '2' }
_.pick(object, [props])
創建一個從 object 中選中的屬性的對象。
var object = { 'a': 1, 'b': '2', 'c': 3 };_.pick(object, ['a', 'c']);
// => { 'a': 1, 'c': 3 }
_.pickBy(object, [predicate=_.identity])
創建一個對象,這個對象組成為從 object 中經 predicate 判斷為真值的屬性。 predicate調用2個參數:(value, key)。
var object = { 'a': 1, 'b': '2', 'c': 3 };_.pickBy(object, _.isNumber);
// => { 'a': 1, 'c': 3 }
Seq、函數
總結:
- 處理數組對象時的 js 方法例如 forEach、map、filter、reduce、find等,使用lodash封裝好的會更加整潔、代碼行數更少。
注意事項
注意事項一: lodash在不同平臺上的使用情況
- 微信小程序可通過該方法引入lodash
如果有用,點個贊唄~
總結用法,希望可以幫助到你,
我是Ably,你無須超越誰,只要超越昨天的自己就好~