介绍
Lodash 是 MIT协议、高性能JavaScript工具函数库,前身是 Underscore.js,作者 John‑David Dalton,提供 300+工具方法,专门处理数组、对象、函数、字符串、集合等常见操作,前端、Node.js都可以使用。
官方
版本
主流稳定版 v4.x,是目前最广泛使用版本。
特点
边界容错能力强
自动处理null / undefined,访问深层属性不会直接抛出Cannot read property错误。模块化
有 CommonJS、ESM(lodash‑es)、fp函数式版本,支持按需引入,避免全量打包。链式调用
_.chain()可以串联多个数据处理方法,简化连续转换逻辑。兼容性好
兼容现代浏览器、Node,兼容 IE11,抹平各环境JSAPI差异。经过工业验证
大量大厂项目使用,算法经过优化,比手写简易版本更健壮,处理嵌套对象、循环引用场景考虑周全。
包版本区别
| 包 | 模块格式 | Tree‑shaking | 说明 |
|---|---|---|---|
lodash |
CommonJS | 不支持 | Node老项目,import _ from 'lodash' 会引入完整库;可以手动导入单文件lodash/debounce做按需加载 |
lodash‑es |
ESM | ✅支持 | 现代Vue/React/Vite/Webpack项目首选,打包器自动删除未使用函数,体积更小 |
lodash/fp |
函数式版本 | ‑ | 数据放最后,自动柯里化,不可变,适合函数式编程风格项目 |
安装
pnpm 安装
普通版本
pnpm add lodash
pnpm add -D @types/lodash
现代项目(适合vue)
安装 lodash‑es
pnpm add lodash‑es
pnpm add -D @types/lodash‑es
导入方式
// ❌不推荐:全量引入lodash,打包体积大
import _ from 'lodash'
// ✅方式1:lodash‑es 直接解构,tree‑shaking生效(vite/webpack)
import { debounce, cloneDeep, get } from 'lodash‑es'
// ✅方式2:lodash(CJS)单独引入单个函数,避免引入全部库
import debounce from 'lodash/debounce'
import cloneDeep from 'lodash/cloneDeep'
// Node.js CommonJS
const _ = require('lodash')
const debounce = require('lodash/debounce')
六大模块高频API
1. 对象 Object
_.get(obj, path, defaultValue):安全读取深层属性,路径可以字符串'a.b.c'或者数组['a','b','c']const obj = {a:{b:1}} _.get(obj,'a.b',0) //1 _.get(obj,'a.x.y',0) //0,不会报错_.set(obj,path,value):安全设置深层属性_.cloneDeep(value):递归深拷贝,支持对象、数组、Date、RegExp;注意不能拷贝函数、循环引用会报错_.merge(obj1,obj2):深度合并对象(区别于Object.assign浅合并)_.pick(obj,['name','age']):只保留指定key_.omit(obj,['password']):剔除指定key_.isEqual(a,b):深度对比两个值是否相等
2. 数组 Array
_.groupBy(list,key):按字段分组const list = [{type:'a',id:1},{type:'b',id:2},{type:'a',id:3}] _.groupBy(list,'type') // {a:[{type:'a',id:1},{type:'a',id:3}], b:[{type:'b',id:2}]}_.sortBy(list,key):按字段排序,返回新数组,不修改原数组_.uniqBy(list,key):按对象字段去重_.difference / intersection / union:集合差集、交集、并集_.partition(list,fn):把数组分成满足条件、不满足条件两组_.compact(arr):过滤掉null,undefined,false,0,''假值
3. 函数 Function(最常用)
_.debounce(fn,wait):防抖,多次触发合并成一次执行(搜索框输入)_.throttle(fn,wait):节流,单位时间最多执行一次(滚动、resize)⚠️React/Vue组件中,组件销毁务必调用
.cancel()清除定时器,防止内存泄漏。_.memoize(fn):缓存函数返回结果_.curry(fn):柯里化
4. Lang 类型判断
_.isNil(val) // 判断 null / undefined
_.isEmpty(val) // 判断空对象、空数组、空字符串
_.isObject() _.isArray() _.isString() _.isNumber()
5. String 字符串
_.trim、_.upperCase、_.camelCase(转驼峰)、_.snakeCase
6. 链式调用 chain
const data = _.chain(list)
.filter(x=>x.age>18)
.sortBy('age')
.map('name')
.value() //必须调用.value()取出结果
⚠️v4版本已经移除惰性求值,链式只是语法糖,不会提升性能。
lodash vs 现代原生JS
ES6+很多能力原生已经实现,不需要一味使用lodash。
| 功能 | Lodash写法 | 现代原生JS |
|---|---|---|
| 安全读取深层属性 | _.get(obj,'a.b.c') |
obj?.a?.b?.c |
| 数组去重 | _.uniq(arr) |
[...new Set(arr)] |
| 深拷贝 | _.cloneDeep(obj) |
structuredClone(obj)(不支持函数) |
| 对象取值过滤 | _.pick() |
需要手写reduce |
| 防抖节流 | _.debounce / _.throttle |
没有原生API,lodash依然首选 |
| 对象深度合并 | _.merge() |
无原生,需要手写递归 |
| 对象深度相等判断 | _.isEqual() |
无原生 |
结论:
- 简单数组map/filter/find优先原生
- 防抖节流、深合并、深度相等、groupBy、pick/omit、安全路径取值 仍然非常适合lodash。
优点与缺点
优点
- 大量成熟工具,不用手写重复逻辑,减少bug
- 大量边界情况已经处理,null、undefined、嵌套对象
- API统一,跨环境行为一致
- 文档完善,社区庞大
缺点
- 全量引入包体积大;必须注意导入方式,优先lodash‑es或者单文件导入
- ES标准持续迭代,部分API已经有原生替代
- 增加项目依赖;小项目如果只用一两个方法可以考虑手写实现
应用场景
Lodash 本质就是弥补 JS 原生 API 的短板,原生能简单搞定的就不用它;原生处理麻烦、边界多、需要写重复工具函数的场景,就是 Lodash 的主场。
1. 对象处理(后台返回嵌套JSON最常用)
后端返回复杂嵌套接口数据,经常存在字段缺失、null/undefined。
- 安全读取嵌套属性
_.get,避免Cannot read properties of undefined。几乎不用,原生已经支持 - 深拷贝
cloneDeep:复制复杂对象/数组,Vue/React 状态备份、表单数据备份。 - 深度合并对象
merge:多层配置合并、多接口返回数据融合(Object.assign只能浅合并) - 字段筛选
pick / omit:过滤对象属性,剔除敏感字段、只保留需要提交的字段。 - 深度相等对比
isEqual:对比两个复杂对象/数组是否完全相等,表单校验、状态变更判断。
原生局限: ?. 只能读取,不能安全 set;没有原生深合并、没有原生深度对象比较。
2. 数组集合处理
前端拿到后端列表,做转换、分组、去重、筛选。
- 分组
groupBy:把列表按类型、状态分组,比如订单按状态分组,人员按部门分组。 - 对象数组去重
uniqBy:根据 id/name 去重对象数组,Set只能处理简单基本类型。 - 集合运算
union / difference / intersection:求并集、差集、交集。 - 分割数组
partition:一次性把数组分成符合条件、不符合条件两组。 - 清理假值
compact:清除数组中null undefined '' false 0。 - 排序
sortBy:多字段排序,返回新数组,不改动原数组。
原生局限: map/filter/reduce 可以实现,但要手写大量循环逻辑,边界需要自己处理。
3. 事件性能优化(高频!防抖节流)
JS没有原生防抖节流,这是 Lodash 使用最高频场景
debounce 防抖:搜索框输入联想、表单输入校验,短时间多次触发只执行最后一次。throttle 节流:窗口滚动、窗口resize、鼠标移动,限制单位时间最多执行一次。
Vue/React组件销毁,调用 .cancel() 清除定时器,防止内存泄漏。
4. 函数工具
memoize:缓存纯函数计算结果,重复相同参数直接取缓存,大数据计算优化。curry柯里化:函数式编程,拆分多参函数。
5. 数据格式化、字符串转换
- 大小写转换、驼峰互转
camelCase / snakeCase,后端下划线字段 ↔ 前端驼峰字段互相转换。 - 字符串修剪、单词格式化。
6. 配置、默认值处理
_.defaults:给对象填充默认配置,缺失的key补上默认值,已有key保留原值。
7. 链式处理多步数据转换
_.chain(),连续做过滤、排序、映射,数据流水线处理。
哪些场景优先用 Lodash
- 接口返回嵌套复杂JSON,对象深拷贝、深度合并、深度比较、安全取值
- 对象数组操作:分组、按字段去重、集合运算
- 防抖、节流(几乎必用)
- 不想手写大量边界判断(自动兼容
null / undefined)
哪些场景不建议引入 Lodash
- 简单数组 map filter find,ES6原生完全够用
- 简单单层对象拷贝,直接展开运算符
{...obj} - 简单基本类型数组去重
[...new Set(arr)]
项目举例
- 管理后台:大量表格数据,列表分组、筛选、字段过滤、表单深拷贝、配置合并
- 搜索页面:输入框
debounce防抖请求接口 - 大屏可视化:滚动/resize事件节流;后端复杂数据做转换分组
- 表单系统:表单对象深拷贝、剔除密码等敏感字段、对比表单前后数据变化