js 判空值 最佳实践

48 天前
 mqnu00

变量 a

我通常是

if (a) {...}

但是会遇到数字 0 的情况,那就是

if (a !== null && a !== undefined) {...}

然后想着是不是要封装一个isEmpty函数 请问需要封装吗?

6007 次点击
所在节点    JavaScript
74 条回复
ragnaroks
47 天前
不嫌麻烦的话 zod 是最优解
94
47 天前
其实相关业务就会很明确输入的内容会是什么东西,同样的你可能还需要判断:

- 是否是 '';
- 是否是 NaN;
- 是否是 [];
- 是否是 {}。

这些情况下都没有很好的方法直接判断,比如说上面提到的 `lodash.isNil()`,`??`。特别是值是 NaN 的时候基本上都会失效。

所以其实按照实际业务情况做判断就好了,先判断是不是需求的值类型,然后判断是不是为对应的空值。
除非说没办法保证输入的数值类型。但是大部分输入输出都是有预期设计好的类型。
wangtian2020
47 天前
出现 null 就把后端骂一顿,然后你就只需要判断 undefined 了
weixiangzhe
47 天前
isNil 和 ?? optional chaining 呀
!! 空符串和 0 啥的真的会教做人吧
shunia
47 天前
判空通常来说就是判空值,在 JS 里也就是 null 和 undefined ,其他所有的判断都是业务需求,并不属于判空。因为 0 也好,NaN 也好,都是有值的。
0xsui
47 天前
_.isNil(null); // true
_.isNil(undefined); // true
_.isNil(''); // false (空字符串不是 nil )
_.isNil(0); // false ( 0 不是 nil )
_.isNil([]); // false (空数组不是 nil )
_.isNil({}); // false (空对象不是 nil )

// 实际场景:接口返回字段判空
const user = { name: '张三', age: undefined, address: null };
if (_.isNil(user.age)) { /* 处理 age 为空的逻辑 */ }
if (_.isNil(user.address)) { /* 处理 address 为空的逻辑 */ }
strickczq
47 天前
apps.apple.com 泄露出来的代码刚好有这方面的:

shared/utils/src/optional.ts

```typescript
export type Optional<T> = T | None;
export type None = null | undefined;

/**
* Determine if an optional value is present.
*
* @param optional value
* @return true if present, false otherwise
*/
export function isSome<T>(optional: Optional<T>): optional is T {
return optional !== null && optional !== undefined;
}

/**
* Determine if an optional value is not present.
*
* @param optional value
* @return true if not present, false otherwise
*/
export function isNone<T>(optional: Optional<T>): optional is None {
return optional === null || optional === undefined;
}
```

可以参考参考
strickczq
47 天前
判断 null 和 undefined 的函数,比起 isEmpty/isNil/isNone ,我更倾向于叫它 isNullish 。
毕竟 MDN 里 `??` 叫做 `nullish coalescing operator`
zhengfan2016
47 天前
@wangtian2020 但是很多中小公司都是后端骑在前端头上的吧,前端基本没话语权
zhengfan2016
47 天前
@yhxx lodash 的 isEmpty 好像只能判断 obj 和 array 吧,对于原生类型好像全返回 true ,比如_.isEmpty(1) // true

https://lodash.com/docs/4.17.15#isEmpty
shintendo
47 天前
@tyrone2333
@Xheldon
@xuejianxianzun
@weixiangzhe
前面说用??的是认真的吗? if 条件里怎么用??判空,想开开眼界

@AtlantaANiu 这个!(a??true)你再看一下? a=null 和 a=1 结果是一样的

@mqnu00 楼主你第二个 append 里的 if (a != null)和 if (!a ?? true)两个不等价你发现了吗,a=null 代入看看?
momocraft
47 天前
不如不要写取值范围这么广的变量
mqnu00
47 天前
@shintendo 感谢提醒。?? 可以归类 null 和 undefined ,对于其他类型是返回原值,接下来通过 ! 实际还是走了转 bool 的操作,那就又回到 if(0)这种类似的情况了。
xmdbb
47 天前
我记得早期 N 年前,直接判断 a===undefined 会报错,好像是 IE 还是什么,太久忘记了,所以养成了习惯都写 typeof a === undefined
AtlantaANiu
47 天前
@shintendo

你说的对,欠考虑了。无论如何右边必须是一个能标识出 null 和 void 0 的唯一值

比如:
const _nil = Symbol('nil')
(a??_nil) === _nil

但这已经不够简洁了。
Ketteiron
47 天前
```typescript
function isEmpty(a: unknown) {
if (a === null || a === undefined) {
return true
} else if (typeof a === 'string') {
return a === ''
// 如果空字符串不认为是空值
// return false
// 或者这样
// return a.trim().length === 0
} else if (Array.isArray(a)) {
return a.length === 0
} else if (typeof a === 'number') {
return false
// NaN 实际上不是空数值,不应该这样使用下面的判断
// return Number.isNaN(a)
} else if (a instanceof Map || a instanceof Set) {
return a.size === 0
} else if (typeof a === 'object') {
const proto: unknown = Object.getPrototypeOf(a)
if (proto === Object.prototype || proto === null) {
return Reflect.ownKeys(a).length === 0
}
}
return false
}
```
发现自从我写 ts 之后,再也没写过这种类似的辅助函数了,没时间跟隐藏的运行时异常打架
https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABFApgZygRgBQEMBciA5EYgD7G6kUBGccANirkhQAzmKYCUiA3gFgAUIkQxgiPL0EjRiCAjSMUAOgZwA5lOFzEAej26jiAHoB+HYgC+iFAzQp+l0QrBKmazdtmiDx3eaWVsJWQA
cheng6563
47 天前
就算是 js ,也不会往一个字段里一会放 number 一会放 string 吧
shintendo
47 天前
@AtlantaANiu 如果这种形式的话,也不用 Symbol ,(a ?? null) === null 就行了,但这样相当于??只用来处理 undefined 一个值,可读性牺牲有点大
shintendo
47 天前
@xmdbb 你说的情况是变量 a 未定义,直接取值就会报错,需要 typeof a
不用 N 年前也不用 IE ,现在打开 chrome 控制台执行 a===undefined 也是报错的
AV1
47 天前
用 ts ,避免同一个变量承受太多样的类型,就没那么多烦恼。

比如一个类型是 value: {...} | undefined ,那我直接 if(value)就够了,根本就没必要担心遗漏 0 、false 、''。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1170998

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX