JavaScript 中 0, null, undefined, “”, NaN 的详解
一、核心特性对比表
值 | 类型 | 布尔值 | 相等性(==) | 特殊行为 |
---|---|---|---|---|
0 | number | false | 与 '' 等价 | 数值零 |
null | object | false | 与 undefined 等价 | 空对象引用 |
undefined | undefined | false | 与 null 等价 | 未定义值 |
"" | string | false | 与 0 等价 | 空字符串 |
NaN | number | false | 与自身不等 | 非数字值,表示无效数学运算结果 |
二、逐项解析
1. 0
(数值零)
核心特性:
- 数值类型的基础值
- 在布尔上下文中被视为
false
- 空值表示(如初始状态、重置数值)
代码示例:
if (0) console.log("不会执行"); // falsy值
// 类型检测
typeof 0 === "number" // true
// 隐式转换
console.log(0 == ""); // true
console.log(0 === ""); // false
常见陷阱:
- 与空字符串的宽松相等性可能导致逻辑错误
- 与
NaN
的比较需特别注意
2. null
(空对象引用)
核心特性:
- 表示有意设置的空值
- 类型为
object
(历史遗留问题) - 用于主动清空对象引用
代码示例:
let user = { name: "Alice" };
user = null; // 清空引用
// 类型检测
typeof null === "object"; // true ❗
// 严格判断
null === null; // true
null == undefined; // true
最佳实践:
- 显式赋值
null
表示主动释放内存 - 使用
===
区分null
和undefined
3. undefined
(未定义)
核心特性:
- 变量声明未赋值时的默认值
- 对象属性不存在时的返回值
- 函数无返回值时的默认返回值
代码示例:
let x;
console.log(x); // undefined
// 属性访问
const obj = {};
console.log(obj.missingProp); // undefined
// 函数返回
function noReturn() {}
console.log(noReturn()); // undefined
常见陷阱:
- 全局
undefined
可被重写(ES5+ 已修复) - 与
null
的宽松相等性可能导致混淆
4. ""
(空字符串)
核心特性:
- 字符串类型的初始值
- 表示无内容的字符串
- 在布尔上下文中为
false
代码示例:
// 常见使用场景
let input = "";
if (!input) console.log("请输入内容");
// 转换行为
console.log("" == 0); // true
console.log("" === 0); // false
性能优化:
- 避免频繁创建空字符串
- 检测空字符串应使用
str === ""
5. NaN
(非数字)
核心特性:
- 表示无效的数学运算结果
- 唯一不等于自身的值
- 传播性:
NaN
参与的运算结果都是NaN
代码示例:
// 产生NaN的情况
console.log(0 / 0); // NaN
console.log(Number("abc")); // NaN
// 检测NaN
console.log(isNaN(NaN)); // true
console.log(NaN !== NaN); // true
// ES6新增
console.log(Number.isNaN(NaN)); // true
特殊规则:
- 不能通过
===
判断自身 isNaN()
会强制转换参数(推荐Number.isNaN()
)
三、相等性比较矩阵
表达式 | 结果 | 说明 |
---|---|---|
0 == null | false | 数值与对象不等 |
0 == "" | true | 宽松相等转换 |
null == undefined | true | 特殊规定 |
NaN == NaN | false | NaN 不等于自身 |
"" === 0 | false | 类型不同 |
Number("abc") | NaN | 字符串转换失败 |
四、常见面试题解析
1. 为什么 null == undefined
是 true?
这是 JavaScript 设计的历史遗留问题。在规范中规定
null
和undefined
是宽松相等的,但严格相等下类型不同。
2. 如何正确判断 NaN
?
使用
Number.isNaN()
(推荐)或value !== value
(利用 NaN 不等于自身的特性)。
3. 0
和 ""
为什么宽松相等?
因为两者在转换为布尔值时都为
false
,且在宽松相等比较中都会被转换为数值类型。
4. typeof null
为什么返回 “object”?
这是 JavaScript 最初实现时的 bug,为了保持向后兼容一直保留至今。