变量 a
我通常是
if (a) {...}
但是会遇到数字 0 的情况,那就是
if (a !== null && a !== undefined) {...}
然后想着是不是要封装一个isEmpty函数
请问需要封装吗?
总结一下大家的内容
Js 判空应结合业务场景
在大多数场景下,仅考虑值为 null 或 undefined 判空时,可以使用以下方式:
if (a != null) { ... } // #2if (!a ?? true) { ... } // #9lodash isNil而在更复杂的场景中,如果还希望将以下值也视为“空”:
[](空数组){}(空对象)NaN''(空字符串)则需要更广义的判空逻辑。复杂之处在于:
=== 是引用比较,无法判断结构是否为空。因此,大家更倾向于使用公认的封装函数,比如 lodash isEmpty,而不是自己封装。
基于#51的提醒,附言1提到的
if (!a ?? true) {...}
实际指的是
if(!(a ?? true)) {...}
但是无法只判断null或undefined为空。
1
liuwk 1 天前 [null,undefined,'',false].includes(a) 我都这样写的
|
2
USDT 1 天前 if (a != null) {
// a is not null or undefined } 没想到吧,==这种邪教在这里居然有用😏 |
3
toy007 1 天前
第二种漏了: 空字符串 '', 非数字 NaN
|
4
coldmonkeybit 1 天前
我们是写了个 isEmpty 判断
|
5
toy007 1 天前
|
6
craftsmanship 1 天前 via Android
2 楼正解 最简洁的形式 但对 JS 各种怪癖不熟悉的人来说可读性很差
|
7
shintendo 1 天前
if (a || a === 0)
|
8
zsc8917zsc 1 天前
@USDT #2 ==挺好的还能对比 1 和'1' ,魔功自古讲究一个简单粗暴好用
![]() |
9
AtlantaANiu 1 天前 !(a??true)
|
12
FakerLeung 1 天前
@USDT #2 好用是好用,但是会被门禁拦下来
|
13
marcong95 1 天前
当时我刚开始用 Standard JS 代码规范的时候,就看到了关于等号的用法里面就学会了用 == 判空这种魔幻用法
Always use === instead of ==. Exception: obj == null is allowed to check for null || undefined. |
14
hronro 1 天前
@FakerLeung 门禁是指 ESLint 之类的?我记得 ESLint 对 == 的使用,是可以配置成只允许 == null 的
|
15
han3sui 1 天前 直接 lodash-es isEmpty()
|
16
jsq2627 1 天前 别封装,对于阅读代码的人,看到 isEmpty 并不知道内部实现是怎样的,对 0 / NaN / '' 是怎么处理的,还要点进去看,很麻烦
就用 if (a !== null && a !== undefined) {...} 一目了然,不管是熟手还是新手都知道在干什么。 |
17
Ulduar 1 天前
|
18
shakaraka PRO 接口层用 zod 保证入参,在业务中用 ts 保证业务类型。少封装这种。不然一会给你个正常的空值你拿来当 else ,除了问题你都不知道是哪里出的
|
19
tyrone2333 1 天前 ?? 和 ?. 了解一下
|
20
NerbraskaGuy 1 天前 用!!吧,虽然可读性很差,追求可读性的话就是枚举一遍了
|
21
leegradyllljjjj 1 天前 via iPhone
我都是在同项目翻其他文件看别人代码是怎么写的,直接靠屁过来,到时候翻车了直接推锅
|
22
huiyuanai709 1 天前
首先加上 typeof a == 'undefined'
|
23
SpiritQAQ 1 天前
isNil?
|
24
mizuki9 1 天前
const NoneSymbol = Symbol("none");
const isNone = (val: unknown): val is null | undefined => { return (val ?? NoneSymbol) === NoneSymbol; }; |
25
yhxx 1 天前
抄一下 lodash.isempty 就行了,有现成的
|
26
Ketteiron 1 天前 我的建议是别用 js 了,换 ts ,0 false undefined null '' [] {} 没有任何歧义
甚至就算写 js 也可以用 ts 规则检查,人脑的静态检查永远比不过语言类型 |
27
jsq2627 1 天前 我补充一下我上面 #16 的回复,这种要不就别封装,要不就直接用 lodash 这种大家都熟悉的库,至少文档清晰,有 bug 一般也不会怀疑它的内部实现。
下图我节选一个我项目中遇到的情况,封装了一百多个 utils function ,每个都不复杂,实现也很精巧,这些 utils 是一位很有经验的高级程序员写出来的。 但是,每次我阅读业务代码时看到 isNil / isEmpty / isTrue 这种,都会想里面是不是有什么魔法,会浪费很多时间点进去看细节。而且对 AI coding 也很不友好,要到处读文件去看实现,不像 lodash 或者直接 inline 有 well-defined behavior 。 ![]() |
28
netnr 1 天前
C# 味
isNullOrWhiteSpace: (value) => value == null || value.toString().trim() == "", |
29
zogwosh 1 天前
只有一个最佳实践,额外封装一个 isEmpty 给自己用,把需要判空的 case 加入判断,即便项目内已经存在了其他同事封装的相同方法,安装了 lodash 。
不要考虑其他同事的阅读性,因为事实就是没有人有动力去用不熟悉的代码的封装,除非必须或有大手推动。 |
31
Xheldon 1 天前
只有少数几个人答对了,用 `??`
|
32
xuejianxianzun 1 天前
空值合并运算符 `??` 是一个逻辑运算符,当左侧的操作数为 `null` 或者 `undefined` 时,返回其右侧操作数,否则返回左侧操作数。
|
33
Ketteiron 1 天前 @mqnu00 js doc 只能定义静态的简单类型,它没法判断一个变量经过某个逻辑判断后变成了什么模样。
例如一个参数可以同时是值、数组或函数,这很常见,ts 中如果你用 if(typeof 判断出是什么具体类型,数组分支里点号按一下数组的可用函数列表就出来了,函数分支里才能(),逻辑越复杂代码越长,ts 对可读性的帮助越大。 ts 开启 checkJs 后会尽力检查 js 文件每一行代码在上下文里是否正确的,不过帮助有限,如果写上 js doc 就可以更精确地检查类型,再加上 typescript-eslint ,像某个角落漏了 await 也能查出来。 |
34
l864494871 22 小时 40 分钟前 via iPhone
判断 null 用==即可
|
35
Valid 22 小时 38 分钟前
数字 0 在哪里都不是 empty 啊
|
36
Valid 22 小时 37 分钟前
!'' !NaN !null !undefined 都是 true ,所以!a 够用了,除非 a 是[]or{}
|
37
zhlssg 22 小时 36 分钟前
无脑选 _.isNil
|
38
rekulas 22 小时 30 分钟前
一般用!!val 就够了,大部分情况都有效,也不像其他语法糖挑版本
|
39
okakuyang 22 小时 0 分钟前
两个感叹号用了几年,从来没考虑过有没有异常情况,看上面这么多回复感觉有点奇怪了。
|
41
ragnaroks 19 小时 36 分钟前
不嫌麻烦的话 zod 是最优解
|
42
94 12 小时 45 分钟前 其实相关业务就会很明确输入的内容会是什么东西,同样的你可能还需要判断:
- 是否是 ''; - 是否是 NaN; - 是否是 []; - 是否是 {}。 这些情况下都没有很好的方法直接判断,比如说上面提到的 `lodash.isNil()`,`??`。特别是值是 NaN 的时候基本上都会失效。 所以其实按照实际业务情况做判断就好了,先判断是不是需求的值类型,然后判断是不是为对应的空值。 除非说没办法保证输入的数值类型。但是大部分输入输出都是有预期设计好的类型。 |
43
wangtian2020 12 小时 29 分钟前
出现 null 就把后端骂一顿,然后你就只需要判断 undefined 了
|
44
weixiangzhe 11 小时 17 分钟前 via Android
isNil 和 ?? optional chaining 呀
!! 空符串和 0 啥的真的会教做人吧 |
45
shunia 10 小时 53 分钟前
判空通常来说就是判空值,在 JS 里也就是 null 和 undefined ,其他所有的判断都是业务需求,并不属于判空。因为 0 也好,NaN 也好,都是有值的。
|
46
0xsui 10 小时 50 分钟前
_.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 为空的逻辑 */ } |
47
strickczq 10 小时 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; } ``` 可以参考参考 |
48
strickczq 10 小时 41 分钟前
判断 null 和 undefined 的函数,比起 isEmpty/isNil/isNone ,我更倾向于叫它 isNullish 。
毕竟 MDN 里 `??` 叫做 `nullish coalescing operator` |
49
zhengfan2016 10 小时 32 分钟前
@wangtian2020 但是很多中小公司都是后端骑在前端头上的吧,前端基本没话语权
![]() |
50
zhengfan2016 10 小时 28 分钟前
@yhxx lodash 的 isEmpty 好像只能判断 obj 和 array 吧,对于原生类型好像全返回 true ,比如_.isEmpty(1) // true
https://lodash.com/docs/4.17.15#isEmpty |
51
shintendo 9 小时 57 分钟前 @tyrone2333
@Xheldon @xuejianxianzun @weixiangzhe 前面说用??的是认真的吗? if 条件里怎么用??判空,想开开眼界 @AtlantaANiu 这个!(a??true)你再看一下? a=null 和 a=1 结果是一样的 @mqnu00 楼主你第二个 append 里的 if (a != null)和 if (!a ?? true)两个不等价你发现了吗,a=null 代入看看? |
52
momocraft 9 小时 54 分钟前
不如不要写取值范围这么广的变量
|
53
mqnu00 OP @shintendo 感谢提醒。?? 可以归类 null 和 undefined ,对于其他类型是返回原值,接下来通过 ! 实际还是走了转 bool 的操作,那就又回到 if(0)这种类似的情况了。
|
54
xmdbb 7 小时 7 分钟前
我记得早期 N 年前,直接判断 a===undefined 会报错,好像是 IE 还是什么,太久忘记了,所以养成了习惯都写 typeof a === undefined
|
55
AtlantaANiu 6 小时 33 分钟前
@shintendo
你说的对,欠考虑了。无论如何右边必须是一个能标识出 null 和 void 0 的唯一值 比如: const _nil = Symbol('nil') (a??_nil) === _nil 但这已经不够简洁了。 |
56
Ketteiron 6 小时 26 分钟前
```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 |
57
cheng6563 6 小时 6 分钟前
就算是 js ,也不会往一个字段里一会放 number 一会放 string 吧
|
58
shintendo 6 小时 4 分钟前
@AtlantaANiu 如果这种形式的话,也不用 Symbol ,(a ?? null) === null 就行了,但这样相当于??只用来处理 undefined 一个值,可读性牺牲有点大
|
59
shintendo 6 小时 0 分钟前
@xmdbb 你说的情况是变量 a 未定义,直接取值就会报错,需要 typeof a
不用 N 年前也不用 IE ,现在打开 chrome 控制台执行 a===undefined 也是报错的 |
60
AV1 5 小时 58 分钟前
用 ts ,避免同一个变量承受太多样的类型,就没那么多烦恼。
比如一个类型是 value: {...} | undefined ,那我直接 if(value)就够了,根本就没必要担心遗漏 0 、false 、''。 |
61
LandCruiser 5 小时 19 分钟前 if ( a )够用了,因为这个值是什么类型,什么值,你心里是有数的,如果 a 需要是 0 才继续执行,那你应该 if ( a===0 ),如果这个值既有可能是其他值,又有可能是 0 ,还需要判断这个值是否存在,那这样的代码就是有问题的,要么前端代码有问题,要么服务端设计的返回值有问题。
|
62
cvooc 5 小时 6 分钟前
@cheng6563 有的, 兄弟有的.有相当一部分二椅子组件库的 input 组件做到了,绑定的 value 原本是 number(如后台 get 接口返回的格式化数据是 number)组件内部处理成 string,最终修改后的值是 string(提交到后台 save 接口的格式).当然大多数场景对这个不敏感就是了,全是后端框架转对象时自动序列化的.
|
63
myderr 4 小时 27 分钟前
if (a) {...}
因为我知道 a 这会儿不可能是 0 |
64
lwfre 4 小时 26 分钟前
一致在用 x!=null 来判断。但是刚刚就发现一个错误,有一行代码多写了一个等号,写成了 if (x!==null) 导致一个按钮没显示出来
|
65
tog 4 小时 24 分钟前
@LandCruiser 这个是正解
|