前言

在日常的前端开发中,总是涉及到对数据的处理,比如后端返给你一坨数据,你需要进行处理并回显到页面上,又或者提交form表单到服务端时,你需要将数据处理成后端接口定义的数据结构,而这些都离不开数据处理。

那数据处理有什么好用的工具库吗?lodash当之无愧。

lodash使用

使用:

// 浏览器环境
<script src="lodash.js"></script>
// npm
npm i --save lodash

接下来给大家介绍下我平时开发用lodash最最最常用的一些方法。

一、数组类

1、_.compact(array)

作用:剔除掉数组中的假值假值包括falsenull,0""undefined, 和 NaN这5个)元素,并返回一个新数组。

使用示例

const _ = require('lodash')
console.log(_.compact([0, 1, false, 2, '', 3, undefined, 4, null, 5]));
// 输出 [ 1, 2, 3, 4, 5 ]

项目中的应用:剔除数组中的一些脏数据。

2、_.difference(array, [values])

作用:过滤掉数组中的指定元素,并返回一个新数组

使用示例

const _ = require('lodash')
console.log(_.difference([1, 2, 3], [2, 4]))
// 输出 [ 1, 3 ]
const arr = [1, 2], obj = { a: 1 }
console.log(_.difference([1, arr, [3, 4], obj, { a: 2 }], [1, arr, obj]))
// 输出 [ 1, 3 ]

类似方法

  • _.pull(array, [values]),与_.difference不同之处在于_.pull会改变原数组。
  • _.without(array, [values]): 剔除所有给定值,并返回一个新数组,这个方法的作用和_.difference相同。

项目中的应用:这个可以在某些场景代替掉Array.prototype.filter

3、_.last(array)

作用:返回数组的最后一个元素

console.log(_.last([1, 2, 3, 4, 5]))
// 输出 5

项目中的应用:有了这个方法,就不需要通过arr[arr.length - 1]这样去取数组的最后一项了,比如一个省市区级联选择器Cascader,但传给后端的时候只需要最后一级的id,所以直接用_.last取最后一项给后端。

类似方法

  • _.head(aray)方法,返回数组的第一项
  • _.tail(array)方法,返回除了数组第一项以外的全部元素

顺便一提,我在实际开发项目中还遇到过用数组的pop方法去取最后一项的,然后由于取了两次调用了两次pop,造成了一个bug,让人哭笑不得。

4、_.chunk(array, [size=1])

作用:将数组按给定的size进行区块拆分,多余的元素会被拆分到最后一个区块当中,返回值是一个二维数组。

使用示例

console.log(_.chunk([1, 2, 3, 4, 5], 2))
// 输出: [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]

项目中的应用:比如你需要渲染出一个xx行xx列的布局,你就可以用这个方法将数据变变成一个二维数组arrarr.length代表行数,arr[0].length代表列数

二、对象类

1、_.get(object, path, [defaultValue])

作用:从对象中获取路径path的值,如果获取值为undefined,则用defaultValue代替。

使用示例

const _ = require('lodash')
const object = { a: { b: [{ c: 1 }, null] }, d: 3 };
 
console.log(_.get(object, 'a.b[0].c'));
// 输出 1
console.log(_.get(object, ['a', 'b', 1], 4));
// 输出 null
console.log(_.get(object, 'e', 5));
// 输出 5

项目中的应用:这个是获取数据的神器,再也不用写出if(a && a.b && a.b.c)的这种代码了,直接用_.get(a, 'b.c')搞定,_.get里面会帮你做判断,绝对省事!

2、_.has(object, path)

作用:判断对象上是否有路径path的值,不包括原型

使用示例

const _ = require('lodash')
const obj = { a: 1 };
const obj1 = { b: 1 }
 
const obj2 = Object.create(obj1)
 
console.log(_.has(obj, 'a'));
// 输出 true
console.log(_.has(obj2, 'b'));
// 输出 false

项目中的应用:这个可以代替Object.prototype.hasOwnProperty,判断对象上有没有某个属性。

3、.mapKeys(object, [iteratee=.identity])

作用:遍历并修改对象的key值,并返回一个新对象。

使用示例

const _ = require('lodash')
const obj = { a: 1, b: 1 };
 
const res = _.mapKeys(obj, (value, key) => {
    return key + value;
})
console.log(res)
// 输出 { a1: 1, b1: 1 }

项目中的应用:调接口传递给后端数据时,如果定义的key和后端接口数据结构定义的key不匹配,可以用_.mapKeys进行适配。

4、.mapValues(object, [iteratee=.identity])

作用:遍历并修改对象的value值,并返回一个新对象。

使用示例

const _ = require('lodash')
const obj = { a: { age: 1 }, b: { age: 2 } };
 
const res = _.mapValues(obj, (value) => {
    return value.age;
})
console.log(res)
// 输出 { a: 1, b: 2 }

项目中的应用:依次对对象values值进行处理,进行数据格式化,以适配后端接口。

5、_.pick(object, [props])

作用:从object中挑出对应的属性,并组成一个新对象

使用示例

const _ = require('lodash')
const obj = { a: 1, b: 2, c: 3 };
 
const res = _.pick(obj, ['a', 'b'])
console.log(res)
// 输出 { a: 1, b: 2 }

项目中的应用:从后端接口中,pick出对应你需要用的值,然后进行逻辑处理和页面渲染,或者pick对应的值,传给后端。

6、.pickBy(object, [predicate=.identity])

作用:与_.pick类似,只是第二个参数是一个函数,当返回为真时才会被pick

使用示例

const _ = require('lodash')
const obj = { a: 1, b: 2, c: 3 };
 
const res = _.pickBy(obj, (val, key) => val === 2)
console.log(res)
// { b: 2 }

项目中的应用:是_.pick的增强版,可以实现动态pick

7、_.omit(object, [props])

作用:_.pick的反向版,忽略掉某些属性后,剩下的属性组成一个新对象。

使用示例

const _ = require('lodash')
const obj = { a: 1, b: 2, c: 3 };
 
const res = _.omit(obj, ['b'])
console.log(res)
// { a: 1, c: 3 }

项目中的应用:代替delete obj.xx,剔除某些属性。

8、.omitBy(object, [predicate=.identity])

作用:_.omit的增强版,第二个参数是一个函数,当返回为真时才会被omit

使用示例

const _ = require('lodash')
const obj = { a: 1, b: 2, c: 3, cc: 4 };
 
const res = _.omitBy(obj, (val, key) => {
    return key.includes('c');
} )
console.log(res)
// { a: 1, b: 2 }

项目中的应用:与_.omit类似。

9、_.set(object, path, value)

作用:给object上对应的path设置值,路径不存在会自动创建,索引创建成数组,其它创建为对象。

使用示例

const _ = require('lodash')
const obj = { };
 
const res = _.set(obj, ['a', '0', 'b'], 1)
console.log(res)
// 输出:{ a: [ { b: 1 } ] }
 
const res1 = _.set(obj, 'a.1.c', 2)
console.log(res1)
// 输出:{ a: [ { b: 1 }, { c: 2 } ] }

项目中的应用:给对象设置值,再也不用设置的时候一层层判断了。

10、_.unset(object, path)

作用:与_.set相反,删除object上对应的path上的值,删除成功返回true,否则返回false

使用示例

const _ = require('lodash')
const obj = { a: [{ b: 2 }] }
 
const res = _.unset(obj, ['a', '0', 'b'])
console.log(res)
// 输出:true
const res1 = _.unset(obj, ['a', '1', 'c'])
console.log(res1)
// 输出:true

项目中的应用:给对象删除值,替换delete a.b.c。使用delete如果在访问a.b.c的时候,发现没有b属性就会报错,而_.unset不会报错,有更加好的容错处理。

三、实用函数

1、_.cloneDeep(value)

作用:标准的深拷贝函数,这个无须多言,用过的人都说好

使用示例

const _ = require('lodash')
const obj = { a: [{ b: 2 }] }
 
const res = _.cloneDeep(obj)
console.log(res)
// 输出:{ a: [ { b: 2 } ] }

项目中的应用:代替JSON.parse(JSON.string(obj))等深拷贝方法,能处理循环引用,有更好的兼容性。

2、_.isEqual(value, other)

作用:深度比较两者的值是否相等

使用示例

const _ = require('lodash')
const obj = { a: [{ b: 2 }] }
const obj1 = { a: [{ b: 2 }] }
 
const res = _.isEqual(obj, obj1)
console.log(res)
// 输出:true

项目中的应用:比较form表单前后的数据是否发生了变化,再也不用自己循环两次+递归去手动比较了。

3、_.isNil(value)

作用:某个值是null或者undefined

使用示例

const _ = require('lodash')
let a = null;
 
const res = _.isNil(a)
console.log(res)
// 输出:true

项目中的应用:有时候我们并不想用if(obj.xx)判断是否有值,因为0也是算有值的,而且可能在后端定义中还有含义,但它转成boolean去判断却是false,所以我们用_.isNil去判断更为准确。

4、_.debounce(func, [wait=0], [options=])

作用:标准的防抖函数,简单理解就是,函数被触发多次,只有最后一次会被触发

使用示例

const _ = require('lodash')
 
const fn = () => ({ 
   fetch('https://xxx.cn/api')
})
const res = _.debounce(fn, 3000)

项目中的应用input输入框的实时搜索,减少接口调用,节约服务器资源。

5、_.throttle(func, [wait=0], [options=])

作用:标准的节流函数,简单理解就是,函数被触发多次,在指定时间范围内只会调用一次

使用示例

const _ = require('lodash')
 
const fn = () => ({ 
   fetch('https://xxx.cn/api')
})
const res = _.throttle(fn, 300)

项目中的应用:监听页面scroll事件滚动加载,监听页面的resize事件等。

6、_.isEmpty(value)

作用:判断一个对象/数组/map/set是否为空

使用示例

const _ = require('lodash')
 
const obj = {}
const res = _.isEmpty(obj);
console.log(res)
// 输出 true

项目中的应用:对传入的数据做非空校验。

7、_.flow([funcs])

作用:传入一个函数数组,并返回一个新函数。_.flow内部从左到右依次调用数组中的函数,上一次函数的返回的结果,会作为下个函数调用的入参

使用示例

const _ = require('lodash')
 
const add = (a, b) => a + b;
const multi = (a) => a * a;
const computerFn = _.flow([add, multi]);
console.log(computerFn(1, 2))
// 输出 9

项目中的应用:我们可以把各种工具方法进行抽离,然后用_.flow自由组装成新的工具函数,帮助我们流式处理数据,有点函数式编程那味儿了。

8、_.flowRight([funcs])

作用:与_.flow相反,函数会从右到左执行,相当于React中的compose函数

使用示例

const _ = require('lodash')
 
const add = (a) => a + 3;
const multi = (a) => a * a;
const computerFn = _.flowRight([add, multi]);
console.log(computerFn(4))
// 输出 19

项目中的应用:与_.flow类似,遇到相关场景,用flow还是flowRight都行,看个人习惯。

小结

以上就是我个人在项目中常用的lodash方法了,使用体验是非常好的,节约了不少处理数据的时间,所以想分享给大家。