javascript过滤接口数据空值需区分基础与深度清理:基础过滤用reduce剔除null/undefined/空字符串;深度过滤递归处理嵌套对象数组,移除空对象、空数组;可配置版本支持自定义无效值范围及字段黑白名单,并可集成axios响应拦截器统一处理。

JavaScript 过滤接口返回数据中的空值和无效字段,核心是判断哪些值属于“空”或“无效”,再递归或逐层剔除。常见无效值包括 null、undefined、空字符串 ''、空数组 []、空对象 {},有时还包括 0 或 false(需按业务决定是否剔除)。
基础过滤:移除 null、undefined、空字符串
适用于扁平对象,用 Object.keys() + reduce 构建新对象:
function cleanEmpty(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
return Object.keys(obj).reduce((acc, key) => {
const val = obj[key];
// 只保留非 null、非 undefined、非空字符串的字段
if (val != null && val !== '') {
acc[key] = val;
}
return acc;
}, {});
}
// 示例
const data = { name: '张三', age: 0, city: '', tags: null, email: 'a@b.com' };
console.log(cleanEmpty(data));
// → { name: '张三', age: 0, email: 'a@b.com' }
深度过滤:递归处理嵌套对象和数组
接口数据常含多层嵌套,需递归判断并清理空对象、空数组等:
- 对数组:过滤掉空/无效项,并对每个元素递归清理
- 对对象:逐个 key 判断,对值递归清理;若清理后对象为空,则整个字段剔除
- 对原始值(string/number/boolean):按需保留或排除(如
0和false默认保留,除非业务明确要删)
示例函数:
function deepClean(obj) {
if (obj === null || obj === undefined) return undefined;
if (Array.isArray(obj)) {
return obj
.map(deepClean)
.filter(item => item !== undefined && !(item === null || (typeof item === 'object' && Object.keys(item).length === 0)));
}
if (typeof obj === 'object') {
const cleaned = {};
for (const [key, val] of Object.entries(obj)) {
const cleanedVal = deepClean(val);
if (cleanedVal !== undefined && !(cleanedVal === null || (typeof cleanedVal === 'object' && Object.keys(cleanedVal).length === 0))) {
cleaned[key] = cleanedVal;
}
}
return Object.keys(cleaned).length ? cleaned : undefined;
}
return obj;
}
按业务定制“无效值”范围
有些场景需要更严格的过滤,比如:
- 把
0、false、NaN也视为空值(慎用,避免误删有效数据) - 忽略仅含空白字符的字符串:
val?.trim() === '' - 排除特定字段名(如
__v、_id),用白名单/黑名单控制
可封装为可配置版本:
function cleanData(obj, options = {}) {
const {
removeFalsy = false, // 是否移除 0/false/''/null/undefined
trimString = true,
keepKeys = [], // 白名单字段(始终保留)
dropKeys = [] // 黑名单字段(强制删除)
} = options;
if (!obj || typeof obj !== 'object') return obj;
const shouldDrop = (key, val) => {
if (dropKeys.includes(key)) return true;
if (keepKeys.includes(key)) return false;
if (val == null) return true;
if (trimString && typeof val === 'string' && !val.trim()) return true;
if (removeFalsy && !val) return true;
return false;
};
if (Array.isArray(obj)) {
return obj.map(v => cleanData(v, options)).filter(v => v !== undefined);
}
return Object.keys(obj).reduce((acc, key) => {
const val = obj[key];
if (shouldDrop(key, val)) return acc;
const cleaned = cleanData(val, options);
if (cleaned !== undefined) acc[key] = cleaned;
return acc;
}, {});
}
配合 Axios 等请求库统一处理响应
在请求拦截器或响应拦截器中自动清理,避免每个接口手动调用:
// Axios 响应拦截器示例
axios.interceptors.response.use(
response => {
if (response.data && typeof response.data === 'object') {
response.data = deepClean(response.data);
}
return response;
},
error => Promise.reject(error)
);
注意:生产环境建议加开关控制(如开发环境开启,线上关闭),避免过度清洗影响调试。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











