讲解

null 和 undefined 都表示「没有值」,但语义不同:undefined 是「系统默认的空」——变量声明了没赋值、函数没写返回值、访问对象不存在的属性、数组越界,得到的都是 undefined;null 是「程序员主动设置的空」——明确表示「这里应该有个值,但我故意让它为空」。简单记:undefined 是意外,null 是约定。

两者有几个语言层面的怪癖要牢记:typeof null 是 'object'(历史 bug,别用它判断 null);typeof undefined 是 'undefined'。宽松相等下 null == undefined 为 true,但它们各自不等于任何其他值;严格相等下 null === undefined 为 false。实践中判断「值是否存在」用 if (value == null) 一次覆盖两种空,是 == 唯一被推荐的用法。

访问可能为空的对象属性是日常高频操作:user.address.city 在 address 为 null 时会抛 TypeError。现代写法用可选链 ?.:user?.address?.city 任一环为空就安全地得到 undefined。配合空值合并 ?? 提供默认值:user?.name ?? '匿名用户'。这两个运算符让防御性代码从层层 if 简化成一行。

示例

// undefined 的几种来源
let notAssigned;
const obj = { a: 1 };
const arr = [1, 2];
function noReturn() {}
console.log(notAssigned, obj.b, arr[99], noReturn()); // 全是 undefined

// null 是主动置空
let currentUser = { name: '小明' };
currentUser = null; // 明确登出
console.log('登出后:', currentUser);

// typeof 的怪癖与正确的判空
console.log(typeof null, typeof undefined);
console.log('宽松:', null == undefined, '严格:', null === undefined);

// 可选链 + 空值合并
const response = { data: null };
console.log(response.data?.user?.name ?? '匿名用户');
console.log(response.data?.list?.length ?? 0);

常见坑

  • 对 null 做属性访问:null.name 直接抛 TypeError,这是前端线上报错的第一大户,要么可选链要么先判空。
  • 用 typeof x === 'undefined' 判 null:typeof null 是 'object',这个判断抓不到 null。
  • JSON 里的差异:JSON.stringify({ a: undefined }) 会丢掉 a 字段,而 null 会保留。接口传参时这个差异可能改变后端行为。
  • 函数默认参数只对 undefined 生效:function f(x = 10) 传 null 不会触发默认值,x 就是 null。

小结

undefined 是系统的「未定义」,null 是你的「置空」;判空用 == null,访问深层属性用 ?.,给默认值用 ??。下一节进入流程控制:条件分支。