Lodash 类型检查怎么选,和 typeof、instanceof 有什么区别?
Lodash 的类型检查方法适合用在输入不稳定、数据来源复杂、需要跨环境判断的场景。原生 typeof 很快,但对数组、日期、null、普通对象的表达不够细;instanceof 能判断构造关系,却容易被 iframe、多运行时环境和原型链改写影响。Lodash 把常见判断拆成了 _.isString、_.isNumber、_.isPlainObject、_.isArrayLike、_.isNil 等方法,读起来更接近业务语言。它的边界也很明确:类型检查只能告诉你“像不像这种值”,不能替代完整的数据校验。
在真实项目里,类型检查通常出现在三处:接口入口、工具函数入口、兼容历史数据的适配层。入口处检查得严一点,可以把错误挡在边界;内部每一行都检查,反而会让代码变啰嗦。还有一个经验是,不要只写判断不写处理策略。发现类型不对以后,是抛错、兜底、丢弃还是上报日志,这些决定比 _.isString 本身更重要。
常用类型检查怎么记
基础类型常用 _.isString、_.isNumber、_.isBoolean、_.isFunction、_.isSymbol。集合和对象常用 _.isArray、_.isObject、_.isPlainObject、_.isMap、_.isSet、_.isTypedArray。空值相关要区分 _.isNil 和 _.isEmpty:前者只匹配 null 与 undefined,后者会把空数组、空对象、空字符串也算作 empty。数字判断里,_.isFinite、_.isInteger、_.isNaN 比原生写法更清晰,但仍要理解 NaN、Infinity 这些特殊值。
jsimport _ from 'lodash'; function normalizeUser(input) { if (!_.isPlainObject(input)) throw new TypeError('user must be object'); return { name: _.isString(input.name) ? input.name.trim() : '', age: _.isInteger(input.age) && input.age >= 0 ? input.age : null, tags: _.isArray(input.tags) ? input.tags.filter(_.isString) : [], active: _.isBoolean(input.active) ? input.active : false }; }
追问
_.isObject 和 _.isPlainObject 有什么区别?
_.isObject 的范围更宽,数组、函数、日期对象都可能被认为是 object,因为它关心的是值是否像对象一样存在引用结构。_.isPlainObject 更窄,主要判断由对象字面量或 Object 构造出来的普通对象。接口入参校验通常更适合用 isPlainObject,因为你多半不希望数组或 Date 混进来。踩坑点是很多人以为 isObject 等同于“普通 JSON 对象”,这会让配置合并、表单解析出现奇怪边界。
_.isEmpty 能不能用来判断字段必填?
可以用,但要非常谨慎。_.isEmpty('')、_.isEmpty([])、_.isEmpty({}) 都是 true,这对表单必填很方便;但 _.isEmpty(0) 和 _.isEmpty(false) 也可能让新人误判,因为数字和布尔值没有可枚举内容。必填校验更推荐先按字段类型分类,再判断空值。比如价格字段允许 0,就不能直接把 isEmpty 当成通用规则。
_.isNumber 会把 NaN 和 Infinity 算作数字吗?
会,NaN 和 Infinity 在 JavaScript 里都属于 number 类型,所以 _.isNumber(NaN) 和 _.isNumber(Infinity) 都会返回 true。业务上如果你要的是“可参与正常计算的有限数字”,应该组合 _.isFinite。这也是类型检查里最常见的坑:语言层面的类型正确,不代表业务层面的值可用。写折扣、库存、分页参数时,最好同时限制整数、范围和有限性。
_.isArrayLike 适合判断哪些值?
它适合判断拥有 length 且可按索引访问的结构,比如字符串、arguments、NodeList。它不等同于真正数组,所以不能默认它有 map、filter 这些数组方法。实际项目里,如果只是要遍历 DOM 查询结果,isArrayLike 很方便;如果要做数组运算,先转成数组更稳。边界在于字符串也可能被判为 array-like,处理前要确认这是不是你想要的结果。
有了 Lodash 类型检查,还需要 Zod、Yup 这类校验库吗?
需要看场景。Lodash 适合轻量判断和局部防御,比如工具函数入口、兼容旧数据、过滤数组元素。Zod、Yup 更适合完整 schema 校验,能给出字段路径、错误信息和类型推导。取舍上,小函数用 Lodash 足够,接口边界、表单提交、复杂嵌套对象用 schema 库更可靠。不要把几十个 _.isXxx 拼成手写校验框架,维护成本会很快失控。
如果项目使用 TypeScript,也不代表运行时检查就完全没必要。TypeScript 只能约束编译期,接口返回、localStorage、URL 参数这些运行时数据仍然可能是错的。Lodash 适合在这些边界做轻量防护,但不要到处重复写同样规则。把判断封装成 isValidUser 这类领域函数,通常比散落一堆 _.isXxx 更容易维护。
类型检查还要考虑错误信息。只返回 false 对调用方帮助不大,尤其是表单和接口调试时,最好说明哪个字段不对、期望什么类型、实际拿到了什么值。Lodash 本身不负责错误聚合,所以复杂对象仍然建议交给 schema 校验。它更像一把小刀,适合快速切开局部问题,不适合替代整套质检流水线。
小结
Lodash 类型检查的价值在于把含糊的原生判断变得清楚:普通对象、空值、有限数字、类数组都能直接表达。它适合做业务代码里的防御式判断,但不适合承担完整数据契约。判断类型前先问一句“我要的是语言类型,还是业务可用值”,大多数选择就会变得明确。