6月1日 01:05

Lodash 对象方法怎么选,get、pick、merge 各适合什么场景?

Lodash 的对象方法最适合解决三类问题:安全访问深层字段、从对象中挑选或排除字段、合并配置或接口数据。它的价值不在于“方法多”,而在于把一些容易写错的边界封装掉。尤其是后台返回结构不稳定、表单字段需要清洗、默认配置要覆盖时,getpickomitmerge 这些方法会比手写判断更省心。

安全读取字段:get、has、set

接口数据里最常见的问题是字段层级深,而且中间某一层可能不存在。直接写 user.profile.email 很容易报错,get 可以给你一个默认值。

js
import get from 'lodash/get'; import has from 'lodash/has'; import set from 'lodash/set'; const email = get(user, 'profile.contact.email', ''); const hasRole = has(user, 'profile.role'); const nextUser = { ...user }; set(nextUser, 'profile.contact.email', 'a@demo.com');

这里要注意一个边界:get 的默认值只在结果是 undefined 时生效,如果字段值是 null,它会返回 null。这在表单里很常见,后端明确返回 null 表示“无值”,和字段不存在不是一回事。

挑选字段:pick、omit、mapValues

当你要把完整对象提交给接口,最好只保留接口需要的字段。pick 适合白名单,omit 适合少量排除。

js
import pick from 'lodash/pick'; import omit from 'lodash/omit'; import mapValues from 'lodash/mapValues'; const payload = pick(form, ['name', 'email', 'role']); const safeUser = omit(user, ['password', 'token']); const trimmed = mapValues(payload, value => typeof value === 'string' ? value.trim() : value );

实际项目里我更推荐提交接口时用 pick,因为它是显式白名单,不会因为前端对象多了临时字段而污染请求。omit 看起来方便,但当敏感字段变多时容易漏掉。

合并对象:assign、defaults、merge

对象合并是 Lodash 里最容易被误用的一类方法。assign 是浅合并,后面的值覆盖前面的值;defaults 只在目标字段为空时填默认值;merge 会递归合并对象。

js
import assign from 'lodash/assign'; import defaults from 'lodash/defaults'; import merge from 'lodash/merge'; const base = { theme: { color: 'blue', size: 'md' } }; const custom = { theme: { size: 'lg' } }; assign({}, base, custom); // { theme: { size: 'lg' } } merge({}, base, custom); // { theme: { color: 'blue', size: 'lg' } } defaults({ pageSize: undefined }, { pageSize: 20 }); // { pageSize: 20 }

merge 适合配置对象,但不适合盲目合并所有业务数据。数组在 merge 里的行为也容易让人意外,它会按索引合并,而不是简单替换。配置合并前最好先写测试,尤其是主题、权限、表单 schema 这类结构。

追问

get 和可选链 ?. 有什么区别?

可选链适合路径固定、字段名确定的场景,例如 user?.profile?.name,原生、直观、没有依赖。get 更适合路径来自配置或字符串的场景,例如表格列配置里写了 profile.name。取舍点在于可读性和动态能力:静态路径优先可选链,动态路径再考虑 get。踩坑点是 get(obj, 'a.b', 'x') 遇到 null 不会返回默认值,如果你希望 null 也兜底,需要自己再用空值合并处理。

pickomit 哪个更安全?

提交接口或保存数据时,pick 通常更安全,因为它只允许白名单字段出去。omit 适合展示层临时隐藏某些字段,比如日志里去掉 token,但它依赖你知道所有需要排除的字段。边界在于需求变化:如果后端新增了 internalNoteomit 可能会直接把它带出去。涉及权限、隐私、支付信息时,宁愿多写几个字段名,也不要用黑名单赌运气。

merge 为什么会把数组合并得很奇怪?

merge 对数组不是整体替换,而是按下标递归合并。比如默认配置里有两个插件,用户配置里只有一个插件,结果可能是第一个被覆盖、第二个还留着。这个行为在合并嵌套配置时有用,但在业务列表上经常不符合直觉。遇到数组建议先明确规则:是替换、追加、去重,还是按 id 合并,不要把所有问题都交给 merge

修改对象时要不要用 set

set 可以快速创建深层路径,但它会修改传入对象,这一点在 React、Redux、Vue 状态管理里尤其要小心。为了避免引用不变导致视图不更新,通常要先复制对象,或者使用不可变更新工具。边界在于普通脚本处理数据时直接 set 没问题,但状态更新里最好别偷懒。踩坑最多的是在 reducer 里 set(state, 'a.b', 1),代码看起来短,实际破坏了不可变约定。

Lodash 对象方法会不会让代码变难懂?

会,尤其是链式调用太长、路径字符串太多时,读者很难知道数据结构长什么样。对象方法应该用在能明显减少边界判断的地方,而不是把简单属性访问都包装起来。团队里可以约定:固定字段用原生写法,动态路径和深层兜底用 Lodash。这样既保留可读性,也不会在异常数据处理上反复写防御代码。

对象方法还有一个现实价值:让接口适配层更集中。比如后端字段命名不稳定时,可以在 mapper 里统一用 getpickmapValues 处理,而不是把防御判断散落在组件里。这样组件只面对稳定的数据结构,调试时也更容易定位问题。代价是适配层需要保持清晰,不能把业务规则和字段搬运混在一起。

小结

Lodash 对象方法的使用重点是“选对场景”。读取深层字段用 get,接口字段白名单用 pick,配置合并再考虑 merge,状态更新时谨慎使用会修改原对象的方法。只要把可读性、数据安全和边界行为想清楚,Lodash 会是补位工具,而不是把业务代码变成工具函数展览。

标签:Lodash