You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤对象中null/undefined属性?不可变对象的简洁实现方案

简洁实现可选属性的对象构建(避免添加undefined/null属性)

刚好碰到过类似的场景,给你几个更简洁的解决方案,尤其是针对对象不可变的情况:

方案1:对象展开 + 短路判断(最常用,不可变友好)

先把异步请求的结果存到变量里,再利用对象展开和短路求值来选择性添加属性,完全不修改原对象:

const bar = await some?.http?.request?.that?.can?.be?.undefined?.or?.null;
const result = {
  foo1: 'foo1',
  foo2: 'foo2',
  foo3: 'foo3',
  // 只有bar不为null/undefined时,才会展开这个{ bar }对象
  ...(bar != null && { bar })
};

这里的逻辑是:当bar != null为真时,&&会返回后面的{ bar },被展开到result中;如果为假,&&返回false,对象展开会忽略布尔值,所以bar属性不会被添加。

方案2:一行式简化写法(注意副作用)

如果不想单独声明bar变量,也可以把逻辑写在一行,但要注意:如果你的异步请求是有副作用的(比如每次调用都会发起实际HTTP请求),这种写法会触发两次请求,不建议用;如果是无副作用的取值(比如从缓存里拿),可以这么写:

const result = {
  foo1: 'foo1',
  foo2: 'foo2',
  foo3: 'foo3',
  ...(await some?.http?.request?.that?.can?.be?.undefined?.or?.null != null && { 
    bar: await some?.http?.request?.that?.can?.be?.undefined?.or?.null 
  })
};

方案3:封装工具函数(适合重复使用)

如果项目里经常需要这种逻辑,封装一个工具函数会更优雅,还能保证类型安全:

function addPropIfNotNull<T extends object, K extends string>(
  baseObj: T,
  propName: K,
  propValue: unknown
): T | (T & { [P in K]: Exclude<typeof propValue, null | undefined> }) {
  if (propValue != null) {
    return { ...baseObj, [propName]: propValue } as any;
  }
  return baseObj;
}

// 使用示例
const bar = await some?.http?.request?.that?.can?.be?.undefined?.or?.null;
const result = addPropIfNotNull(
  { foo1: 'foo1', foo2: 'foo2', foo3: 'foo3' },
  'bar',
  bar
);

这个函数会在属性值有效时返回一个新的带属性的对象,否则返回原对象,完美适配不可变场景。

补充:为什么原方法不适合不可变场景?

原方法是先创建对象再给result.bar赋值,这属于直接修改原对象的属性,违背了不可变对象的原则——不可变对象要求不能修改原对象,必须通过创建新对象来更新内容,所以上面的方案都是基于创建新对象的思路实现的。

内容的提问来源于stack exchange,提问作者TSR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:42:41