JavaScript 里的“空”:Null 与 Undefined 的终极指南

​

在 JavaScript 的世界里,表示"没有"的值竟然有两个:undefined 和 null。这不仅是初学者的噩梦,也是许多资深开发者容易踩坑的面试题。

简单来说,它们的区别可以概括为一句心法:undefined 是意外的空(系统行为),null 是故意的空(人为行为)。

1. 核心概念:盒子的比喻

为了直观理解,我们可以把变量想象成一个盒子:

  • undefined(未定义) :

    你刚买了一个盒子,还没来得及往里面放东西。

    含义:缺少值。变量声明了但未赋值,或属性不存在。

    来源 :通常由 JS 引擎 自动赋予。

  • null(空值) :

    你往盒子里放了一张纸条,上面写着"空"。

    含义:定义了,但是为空。

    来源 :通常由 开发者 手动赋值,用来明确表示"这里不应该有值"。


2. 技术层面的四大差异(面试必考)

虽然它们都代表"假值"(Falsy),但在底层表现上截然不同:

A. 数据类型(Typeof 的历史 Bug)

这是 JS 最著名的历史遗留问题,但为了兼容性一直保留至今。

javascript 复制代码
console.log(typeof undefined); // "undefined"
console.log(typeof null);      // "object"  <-- 注意!

B. 数字转化(数学运算的坑)

当你试图把它们当数字用时,结果完全不同:

javascript 复制代码
console.log(Number(null));      // 0  (空值被视为空白,算作0)
console.log(Number(undefined)); // NaN (Not a Number,非数字)

警示 :5 + null = 5,但 5 + undefined = NaN。如果不小心,你的财务报表可能会因为一个 undefined 全盘崩溃。

C. JSON 序列化(数据消失术)

在前后端交互传输数据时(JSON.stringify):

  • null:会被保留。
  • undefined :会被直接忽略(剔除) 。
javascript 复制代码
const data = { name: "Gemini", age: undefined, bio: null };
JSON.stringify(data); 
// 结果: '{"name":"Gemini", "bio":null}' 
// 注意:"age" 字段直接凭空消失了!

D. 相等性判断

  • 宽松相等 (==) :它们被认为是"一伙的"。
  • 严格相等 (===) :它们泾渭分明。
ini 复制代码
null == undefined  // true
null === undefined // false

3. 最佳实践:为什么永远不要写 a = undefined?

在代码规范中,有一条铁律:永远不要显式地将变量赋值为 undefined。 如果你需要重置一个变量,请使用 null。

理由如下:

① 语义歧义(Ambiguity)

当你看到 let x = undefined 时,你无法判断:

  • 是程序出 Bug 了,忘记给它赋值?

  • 还是开发者故意把它清空的?

    而看到 x = null,你就知道这是开发者有意为之的控制逻辑。

② 默认参数的陷阱(ES6)

函数的默认参数机制(Default Parameters)只认 undefined,不认 null。

scss 复制代码
function config(color = "blue") {
    console.log(color);
}

config(undefined); // 输出 "blue" -> 触发默认值
config(null);      // 输出 null   -> 不触发默认值(系统认为你传了个有效值)

如果你习惯手动赋值 undefined,你会经常意外触发函数的默认逻辑,导致难以排查的 Bug。

③ 防止数据丢失

如前所述,如果你把对象属性设为 undefined,发给后端时这个字段会消失。后端可能认为"前端没传这个字段,那我就不更新数据库",导致数据删除失败。用 null 则能明确传达"置空"的意图。


4. 总结对照表

特性 Undefined Null
一句话定义 应该有值,但还没给 明确设置为空值
主要发起者 JavaScript 引擎 (被动) 开发者 (主动)
Typeof 'undefined' 'object'
转数字 NaN 0
JSON处理 被忽略 (key 消失) 保留为 null
最佳实践 不要手动赋值,仅用于检查 用于重置变量或初始化

最终建议:

让 undefined 留在系统底层,作为一种"缺失"的状态;而在你的业务逻辑代码中,当你想表达"空"时,请始终拥抱 null。

​

相关推荐
孟陬6 小时前
JavaScript 反引号(` backtick)和双引号的不完全等价 ≠ 场景
javascript·node.js·bun
谢亮_vipxieliang6 小时前
深入理解 JavaScript 数据类型与类型转换
开发语言·javascript·ecmascript
程序员Sunday16 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
默_笙17 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
思无邪6618 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
福兮说19 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
可乐鸡翅yeah_20 小时前
video.js 集成 hls.js 开发 M3U8 播放器,新手高频踩坑
开发语言·前端·javascript·后端·ecmascript·m3u8·音视频在线播放
用户117953654781 天前
TRAE vs Claude Code 性能对比:从代码生成、多文件重构到底层吞吐,谁更适合你的日常开发?
javascript
kill5221 天前
useRef
前端·javascript·react.js
米多科技1 天前
我做了一个 3D 虚拟世界基底,在上面再搭 3D 世界或元宇宙,事半功倍
javascript·人工智能·github