Ramda实现的removeNullOrEmpty函数将Date对象转为空数组如何解决
问题原因
- Ramda内置的
isEmpty对Date实例会返回true:isEmpty对对象类型的判断逻辑是检查是否存在可枚举的自有属性,Date实例本身没有可枚举的自有属性,会被误判为空值。 - Ramda的
is(Object, 任意Date实例)返回结果为true:Date属于Object的子类,因此你写的递归逻辑会把Date实例当成普通对象传入removeNullOrEmpty二次处理。当reject方法接收到Date这类非普通对象、非数组的输入时,Ramda的集合处理函数会默认将其转换为空数组,最终就得到了你看到的timestamp: []的结果。
修复方案
调整空值判断逻辑和递归触发条件,排除Date、正则等特殊内置对象的处理,仅对普通对象和数组做递归和空值过滤,参考实现如下:
import { pipe, reject, either, isNil, isEmpty, map, when, both, is } from 'ramda' // 定义不需要做空值判断、也不需要递归的特殊类型,可按需拓展 const isSpecialType = either(is(Date), is(RegExp), is(Function), is(Map), is(Set)) // 普通对象判断,避免把特殊实例当成普通对象处理 const isPlainObject = (val) => Object.prototype.toString.call(val) === '[object Object]' // 修正后的空值判定逻辑:排除特殊类型后再判断是否为空 const isNullOrEmpty = either( isNil, both( val => !isSpecialType(val), isEmpty ) ) export const removeNullOrEmpty = (o) => pipe( reject(isNullOrEmpty), map(when( // 仅对普通对象和数组触发递归 either(isPlainObject, Array.isArray), removeNullOrEmpty )) )(o)
修复后测试之前的复现代码,返回结果会保留正常的Date实例,不会被转换为空数组。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

