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