先记住这个答案
=== 先比类型,null 的类型是 Null,undefined 的类型是 Undefined,类型不同直接返回 false。== 则在 ECMAScript 规范里为 null 和 undefined 专门设了一条规则:二者互相宽松相等,且不会和其他任何值宽松相等。这意味着 value == null 能同时匹配 null 和 undefined,但不会误匹配 0、false 或空字符串。
null === undefined为falsenull == undefined为true- 空值宽松相等有专门规则
value == null是简洁的空值检查写法
null 和 undefined 跟其他假值的比较
0、false、空字符串和 null、undefined 都是假值,但在 == 的世界里它们并不互通。null 和 undefined 组成一个封闭的小圈子:只和对方相等,不会被转成数字去和别人比。
null 和 undefined 不匹配其他假值JavaScriptconsole.log(null === undefined);
console.log(null == undefined);
console.log(null == 0);
console.log(null == false);
console.log(null == '');
console.log(undefined == 0);
console.log(undefined == false);查看输出与解释
false
true
false
false
false
false
false除了 null == undefined 是 true,其余全是 false。如果 == 把 null 转成数字,Number(null) 是 0,那 null == 0 就该是 true。但实际上 null 在 == 里根本不会走 ToNumber 这条路,规范专门规定了它和 undefined 只配对彼此。
这条规则让 value == null 成了一个很好用的写法:它只在 value 是 null 或 undefined 时成立,不会误匹配数字 0 或布尔 false。
value == null 的使用场景和边界
在实际项目里,你经常需要判断一个值是不是"空的"。写成 value === null || value === undefined 有点长,value == null 做的是同一件事,更简洁。不少团队在 ESLint 里开了 eqeqeq 规则但给 == null 留了豁免。
不过也有要区分的时候。比如 GraphQL 请求里,字段缺失(undefined)意味着"不修改这个字段",字段显式传了 null 意味着"清空这个字段"。这时候就不能用 == null 一把抓,需要用 === undefined 或 === null 分别处理,或者检查对象上是否存在这个属性。
Object.is 和 === 对空值的行为JavaScriptconsole.log(Object.is(null, undefined));
console.log(Object.is(null, null));
console.log(Object.is(undefined, undefined));查看输出与解释
false
true
trueObject.is 使用 SameValue 算法,不做宽松转换。它和 === 对 null、undefined 的结果完全一致,区别只在对 NaN 和 -0 的处理上。
容易答错的地方
- 认为
null == 0是true - 直觉上
Number(null)是0,所以很多人以为null == 0也是true。但==遇到null时不会走ToNumber转换,而是直接走配对规则——null只和undefined相等。这是规范里的硬编码特例,和类型转换无关。 - 用
typeof区分null和undefined typeof undefined返回"undefined",但typeof null返回"object"。这是 JavaScript 第一版实现时遗留的 bug,一直没修因为会破坏已有代码。用typeof没法判断null,要判断null可以直接value === null。
面试官还会怎么问?
typeof null 为什么返回 "object"?
JavaScript 最早的实现里,值在内存中用一个类型标签加数据表示。对象的标签是 0,而 null 在底层是空指针(全零),所以 typeof 把它当成了对象。这个行为在 ES6 曾经有提案修复,但因为会破坏太多已有网站被否决了。
怎样只检查 undefined 而不匹配 null?
直接用 value === undefined。如果担心全局变量 undefined 被覆盖(在非严格模式的旧代码里理论上可以),可以用 typeof value === 'undefined',它对未声明的变量也不会报错。
?? 和 == null 判断的范围一样吗?
一样。value ?? fallback 在 value 为 null 或 undefined 时使用 fallback,和 value == null 匹配的范围完全相同。区别是 ?? 用来选值,== null 用来做判断。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。