← [ BACK_TO_NOTES ]

JS中的「null」和「undefined」

JS中的「null」和「undefined」:语义差异、比较行为、JSON 序列化与常见陷阱。

#javascript #synthesis #growing #ecmascript

[!info] related notes

JS中的「null」和「undefined」


在 JavaScript 中,undefined 和 null 都表示“无值”的概念,但它们在语义、使用场景和底层行为上存在显著差异。以下是两者的详细对比与分析:


1. 定义与语义

  • undefined
  • 含义:表示变量已声明但未初始化,或属性/值不存在。由 JavaScript 引擎自动分配,属于原始类型(primitive type)。
  • 示例:
let x;
console.log(x); // undefined
  • 其他场景:函数未显式返回值时默认返回 undefined,访问对象不存在的属性时返回 undefined。
  • null
  • 含义:表示开发者显式赋值的“空值”,通常用于主动标记无对象引用。typeof null 返回 "object"(历史遗留问题)。
  • 示例:
let y = null; // 明确表示 y 无值
console.log(typeof y); // "object"

2. 关键区别

特性undefinednull
类型undefined(原始类型)object(原始值,但类型标签为对象)
赋值方式隐式(引擎自动分配)显式(开发者主动赋值)
比较行为== null 为 true,=== null 为 false=== null 为 true
用途未初始化变量、缺失属性明确清空对象或变量

3. 使用场景建议

  • 优先使用 null 的情况:
  • 需要明确表示“无值”或清空对象引用(如重置变量、数据库空字段)。
  • 与外部系统(如 Java 后端)交互时,null 更通用。
  • undefined 的适用场景:
  • 变量未初始化或函数参数未传递时依赖默认行为。
  • 避免手动赋值 undefined,因其可能被误认为未初始化。

4. 注意事项

  • 类型检查:
  • 使用 === 严格比较区分 null 和 undefined。
  • typeof 无法可靠检测 null(返回 "object"),推荐直接比较 x === null。
  • 默认参数处理:
  • 函数默认参数对 undefined 生效,但对 null 会保留 null 值:
function test(x = 1) { console.log(x); }
test(undefined); // 1(使用默认值)
test(null);// null
  • JSON 序列化:
  • undefined 属性会被忽略,而 null 会保留。

5. 比较行为详解

null 和 undefined 参与比较时的规则分两套:== 的抽象相等,和 < > <= >= 的关系比较。它们不是同一套逻辑,这也是最反直觉的地方。

5.1 === vs ==

null === undefined // false
null == undefined  // true

=== 严格比较,类型不同直接 false。== 里 null 和 undefined 被规范特判为”空值族”,彼此相等。

但它俩只跟彼此相等:

null == 0       // false
null == false   // false
undefined == 0  // false
undefined == false // false

详见 equality-operators。

5.2 null 与关系比较(最坑的部分)

null < 0   // false
null > 0   // false
null <= 0  // true
null >= 0  // true

原因:

  • 关系比较 < > 会把 null 转成数字 0,所以 0 < 0 和 0 > 0 都是 false
  • 但 <= 的规范等价逻辑是”不是 >“,>= 是”不是 <”
  • 因为 null > 0 是 false,所以 null <= 0 为 true
  • 因为 null < 0 是 false,所以 null >= 0 为 true

这就是为什么会出现”不大于 0、不小于 0、但小于等于 0、也大于等于 0”的反直觉结果。

5.3 undefined 与数字比较(全是 false)

undefined == 0  // false
undefined < 0   // false
undefined > 0   // false
undefined <= 0  // false
undefined >= 0  // false

涉及数值比较时 undefined 转成 Number(undefined) 即 NaN,而 NaN 参与任何大小比较都是 false。

5.4 一句话记忆

值数值比较时等价于和 0 比较
null0<= 0 和 >= 0 为 true,但 < 0 和 > 0 为 false
undefinedNaN全部为 false
  • null == undefined 是 true
  • null 数值比较时更像 0
  • undefined 数值比较时更像 NaN
  • NaN 跟任何大小比较都是 false

6. 最佳实践

  • 代码一致性:团队应统一选择 null 或 undefined 以减少混淆,可通过 ESLint 规则强制规范。
  • 内存管理:使用 null 显式释放对象引用,辅助垃圾回收。
  • TypeScript:优先用 undefined 配合可选属性(?),减少 | null 类型联合。

总结

undefined 和 null 分别代表“未定义”与“有意为空”。理解它们的差异有助于编写更清晰、健壮的代码。多数情况下,显式使用 null 更可控,而 undefined 更适合依赖语言默认行为。

学习检查

不看正文回答:

  1. undefined 与 null 在语义上分别更接近“缺省/未提供”还是“显式为空”?
  2. 为什么 null == undefined 为真,但严格相等为假?
  3. 数值比较中 null 与 undefined 分别会怎样转换?
  4. JSON 序列化对象属性时,undefined 与 null 的表现为什么不同?
  5. TypeScript API 设计里,可选字段与显式 nullable 字段分别表达什么契约?
  6. 为什么团队应该明确 nullability 约定,而不是依赖“哪个更推荐”的绝对规则?
创建于 2025/1/1 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本