Lodash-JavaScript的实用工具库

0 阅读8分钟

image

Lodash 入门:从零开始

起源与目标

  前端开发中,数据处理占了业务逻辑的 “半壁江山”,但原生 JavaScript API 在复杂场景下总显得 “力不从心”。而 Lodash 作为前端生态中最经典的工具库之一,提供了很多处理数组、对象、字符串等的便捷方法,旨在简化常见的数组、对象、字符串、函数以及其他数据结构的操作。Lodash 并非 “花里胡哨的工具集合”,而是基于前端开发痛点诞生的 “解决方案库”。它的核心价值,在于用更优雅的方式解决 “原生 API 搞不定或搞不好” 的问题,彻底告别 “数据处理焦虑”。

image

  由于原生 Lodash 库为了保持广泛浏览器兼容性,默认使用 CommonJS 模块格式(适用于Node.js环境和老版浏览器),这可能导致在现代前端项目中引入整个库时,即使只使用其中少数几个函数,也需加载整个库的代码,造成不必要的网络传输和客户端资源消耗。lodash-es 应运而生,旨在为那些支持ES模块的项目提供一个更轻量、更易于优化的Lodash版本。Lodash-es 是流行 JavaScript 工具库 Lodash 的 ES 模块版本,提供了与 lodash 完全一致的 API,但采用原生 ES Module 格式导出,能大幅简化开发中的数据处理、数组/对象操作、函数防抖节流、深拷贝等场景的代码,提升开发效率和代码健壮性。是现代前端工程的首选工具库,配合 Vite、Webpack、Rollup 等打包工具可以实现完美的 Tree Shaking,大幅减少产物体积。

快速集成

安装依赖

如果正在使用 Node.js 的包管理器 npm,打开终端或命令提示符,进入项目根目录,然后执行以下命令:

# 核心库(ES 模块版本)
npm install lodash-es

按需引入

  完成安装后,就可以在项目中导入并使用 lodash-es 提供的工具函数。Lodash-es 支持按需导入,可以显著减少打包体积,是现代 JavaScript 项目中的首选工具库。

// 单函数引入(推荐)
import { debounce } from 'lodash-es';
import { cloneDeep, merge } from 'lodash-es';
import chunk from 'lodash-es/chunk';

// 也可以从单独文件导入(更利于 Tree-shaking)
import debounce from 'lodash-es/debounce';
import throttle from 'lodash-es/throttle';

核心高频功能

数组(Array)

  lodash-es 提供了丰富的数组处理函数,涵盖分块、扁平化、去重、排序等常见场景。

函数简要说明示例
uniq去重uniqBy([{id:1},{id:1},{id:2}], 'id')[{id:1},{id:2}]
difference差集difference([1,2,3],[2,4])[1,3]
intersection交集intersection([1,2,3],[2,3,4])[2,3]
union并集union([1,2],[2,3])[1,2,3]
drop、dropRight去掉前/后 n 个元素drop([1,2,3], 1)[2,3]
take、takeRight取前/后 n 个元素take([1,2,3], 2)[1,2]
fill填充数组fill(Array(3), 'a')['a','a','a']
pull、pullAll、pullAt原地移除元素pull([1,2,3,4], 2, 4)[1,3]
remove原地移除满足条件的元素remove([1,2,3], n => n > 1) → 移除 [2,3],返回 [2,3]
slice截取(不修改原数组)slice([1,2,3,4], 1, 3)[2,3]
sortedIndex、sortedIndexOf有序数组操作sortedIndex([10,20,30], 25)2
without排除指定值(非原地)without([1,2,3,4], 2, 4)[1,3]
findIndex、findLastIndex查找索引findIndex([1,2,3], n => n > 1)1
import { chunk, uniqBy, intersection, flattenDeep } from 'lodash-es'

// 分页分块
const pages = chunk(dataList, 10)

// 按 id 去重
const uniqueUsers = uniqBy(userList, 'id')

// 求共同好友
const commonFriends = intersection(myFriends, theirFriends)

// 递归扁平嵌套数据
const flatList = flattenDeep(nestedData)

集合(Collection)

  lodash-es 集合方法统一处理数组和对象,涵盖分组、排序、查找、转换等数据操作。

函数简要说明示例
forEach、forEachRight遍历forEach([1,2], n => console.log(n))
map(coll, iter)映射map([1,2,3], n => n * 2)[2,4,6]
filter(coll, pred)过滤filter([1,2,3], n => n > 1)[2,3]
reject(coll, pred)排除满足条件的reject([1,2,3], n => n > 1)[1]
find(coll, pred)、findLast查找第一个匹配find([1,2,3], n => n > 1)2
every(coll, pred)是否全部满足every([1,2,3], n => n > 0)true
some(coll, pred)是否有任一满足some([1,2,3], n => n > 2)true
countBy(coll, iter)按条件计数分组countBy(['a','b','a']){a:2,b:1}
keyBy(coll, iter)按 key 组装对象keyBy([{id:1},{id:2}], 'id'){1:{id:1},2:{id:2}}
groupBy按条件分组groupBy([1, 2, 3, 4, 5], n => n % 2 === 0 ? 'even' : 'odd')
sortBy排序sortBy(users, ['name','age'])
includes(coll, val, fromIndex)是否包含includes({a:1,b:2}, 2)true
size(coll)集合大小size({a:1,b:2})2
import { groupBy, orderBy, keyBy, countBy } from 'lodash-es'

// 按部门分组员工
const employeesByDept = groupBy(employees, 'department')

// 按年龄降序、姓名升序排序
const sorted = orderBy(users, ['age', 'name'], ['desc', 'asc'])

// 转 id 为 key 的映射,O(1) 查找
const userMap = keyBy(userList, 'id')
const user = userMap[targetId]  // 快速查找

// 统计各角色人数
const roleCount = countBy(users, 'role')

函数(Function)

  函数工具包括防抖、节流、缓存等性能优化利器,是前端交互优化的常用手段。

函数简要说明示例
debounce(fn, wait, options)防抖debounce(handleSearch, 300)
throttle(fn, wait, options)节流throttle(onScroll, 200)
once(fn)只执行一次once(initApp)
before(n, fn)最多执行 n 次before(3, log)
delay(fn, wait, ...args)延迟执行delay(() => console.log('hi'), 1000)
import { debounce, throttle } from 'lodash-es'

// 防抖:输入停止 300ms 后触发搜索
const handleSearch = debounce((keyword) => {
  fetchSearchResults(keyword)
}, 300)

// 节流:滚动加载,1 秒内最多触发一次
const handleScroll = throttle(() => {
  loadMoreData()
}, 1000)

语言(Lang)

  类型判断、比较、转换。

函数简要说明示例
isEqual深度比较相等isEqual({a:{b:1}}, {a:{b:1}})true
isMatch对象是否匹配子集isMatch({a:1,b:2}, {a:1})true
isEmpty是否为空isEmpty({})true; isEmpty([1])false
isArray是否数组isArray([1])true
isBoolean是否布尔值isBoolean(true)true
isFunction是否函数isFunction(() => {})true
isInteger是否整数isInteger(3)true
isNil是否 null/undefinedisNil(null)true
isNumber是否数字isNumber(3)true
isObject对象判断isPlainObject({})true; isPlainObject(new Date())false
isString字符串/符号判断isString('abc')true
isDate特殊类型判断isDate(new Date())true
isMap、isSet集合类型判断isSet(new Set())true
isArrayBuffer、isTypedArray二进制类型判断isTypedArray(new Uint8Array())true
eq(a, b)严格相等eq(NaN, NaN)true(区别于 ===
gt、gte、lt、lte大于/大于等于/小于/小于等于gt(3, 1)true
castArray将值转为数组castArray(1)[1]; castArray([1])[1]
toArray(val)转为数组toArray({a:1,b:2})[1,2]
toInteger、toNumber
toLength、toSafeInteger
类型转换toInteger(3.7)3

数学(Math)

函数简要说明示例
add、subtract、multiply、divide四则运算add(1, 2)3
ceil、floor、round取整/四舍五入ceil(4.006, 2)4.01
max、maxBy、min、minBy最大最小值maxBy([{n:1},{n:3},{n:2}], 'n'){n:3}
mean平均值mean([4,6])5
sum求和sumBy([{n:1},{n:3}], 'n')4

数字(Number)

函数简要说明示例
clamp(num, min, max)限制在范围内clamp(15, 0, 10)10
inRange(num, start, end)是否在范围内inRange(3, 2, 4)true
random(min, max, floating)随机数random(1, 10)5

对象(Object)

  对象处理是 lodash 最核心的能力之一,涵盖安全取值赋值、深拷贝、属性筛选等,是日常开发中减少样板代码的利器。

函数简要说明示例
get(obj, path, default)安全取值,路径不存在时返回默认值get({a:{b:1}}, 'a.b.c', 'N/A')'N/A'
set(obj, path, val)安全深度赋值set({}, 'a.b.c', 3){a:{b:{c:3}}}
has(obj, path)判断属性是否存在has({a:{b:1}}, 'a.b')true
unset(obj, path)删除属性unset({a:{b:1}}, 'a.b')true
merge(obj, ...sources)深度合并merge({a:1},{b:{c:2}}){a:1,b:{c:2}}
assign(obj, ...sources)浅合并assign({a:1},{b:2}){a:1,b:2}
pick(obj, paths)提取指定属性pick({a:1,b:2,c:3},['a','c']){a:1,c:3}
omit(obj, paths)排除指定属性omit({a:1,b:2,c:3},['b']){a:1,c:3}
keys(obj)、 values获取键/值keys({a:1,b:2})['a','b']
entries(obj)获取 [key, value] 对entries({a:1})[['a',1]]
fromPairs(pairs)数组转对象fromPairs([['a',1]]){a:1}
defaults(obj, ...sources)填充默认值defaults({a:1},{a:3,b:2}){a:1,b:2}
findKey(obj, pred) / findLastKey查找 keyfindKey({a:1,b:2}, v => v > 1)'b'
import { get, set, cloneDeep, omit, merge } from 'lodash-es'

// 安全取值,避免 Cannot read property 错误
const userName = get(response, 'data.user.name', '未知用户')

// 深拷贝表单数据
const formCopy = cloneDeep(originalForm)

// 剔除敏感字段后返回给前端
const safeUser = omit(user, ['password', 'salt'])

// 深度合并配置
const finalConfig = merge({}, defaultConfig, userConfig)

字符串(String)

  字符串处理涵盖命名格式转换、填充、截断等实用工具。

函数简要说明示例
camelCase转驼峰camelCase('foo_bar-baz')'fooBarBaz'
kebabCase转短横线kebabCase('fooBar')'foo-bar'
snakeCase转下划线snakeCase('fooBar')'foo_bar'
lowerCase、upperCase全小写/全大写(按单词分隔)lowerCase('FooBar')'foo bar'
capitalize首字母大写其余小写capitalize('hello')'Hello'
upperFirst、lowerFirst仅首字母大小写upperFirst('hello world')'Hello world'
startCase每个单词首字母大写startCase('--foo-bar--')'Foo Bar'
debar去除变音符号deburr('déjà vu')'deja vu'
startsWith、endsWith前缀/后缀判断startsWith('hello','he')true
escape、unescapeHTML 转义/反转义escape('<div>')'<div>'
escapeRegExp转义正则特殊字符escapeRegExp('(abc)')'$abc$'
truncate截断truncate('hello world',{length:5})'he...'
repeat重复repeat('ab', 3)'ababab'
padStart、padEnd填充padStart('5',3,'0')'005'
pad两端填充pad('abc', 8, '_-')'_-abc_-_'
trim、trimStart、trimEnd去除首尾空白trim(' hello ')'hello'
split(str, sep, limit)分割字符串split('a-b-c','-',2)['a','b']
template(str)编译模板template('hi <%= name %>')({name:'Tom'})'hi Tom'
words(str)提取单词数组words('hello world')['hello','world']
import { camelCase, kebabCase, snakeCase, padStart } from 'lodash-es'

// 后端返回下划线字段转驼峰
const key = camelCase('user_name')  // 'userName'

// 生成 CSS 类名
const className = kebabCase('UserProfile')  // 'user-profile'

// 日期补零
const month = padStart(String(5), 2, '0')  // '05'

总结

  Lodash-es 是现代 JavaScript 开发中不可或缺的工具库。通过按需导入和合理使用,可以显著提升开发效率和代码质量。记住始终使用 ES 模块语法导入,并根据项目需求选择合适的函数,避免不必要的依赖。

image