js null 和 undefined 有什么区别
通过语义来源、typeof、相等比较、默认值及常见场景对比 null 与 undefined,明确 undefined 多由引擎自动产生、null 为开发者主动置空,并给出判断 null 用 === null、检测未声明变量用 typeof
学完这篇你能得到:一套能直接照着排查代码的对比方法,分清 JS 里 null 和 undefined 在语义、类型判断、比较运算、默认值行为上的差异,不再凭感觉写判断。
第一步:先分清语义,一个是“系统没给”,一个是“你主动给的空”
这一步要建立最基本的认知:undefined 表示“这个值还不存在”,通常由 JS 引擎自动产生;null 表示“这个值存在,但我明确设成空”。做完这步,你看到变量就能判断该用哪个。
let a; // 声明了没赋值 → a 是 undefined
let b = null; // 明确告诉后面的人:这里暂时没有值
两者的核心区别在“谁写的”:undefined 是引擎给的默认值,null 是开发者手写的占位符。
注意:不要给变量显式赋 undefined,
let x = undefined和let x效果一样,但会让读代码的人分不清是漏写还是故意。
第二步:记住 typeof 的那个例外
这一步要拿到类型判断的正确结果。typeof undefined 返回 "undefined",符合直觉;但 typeof null 返回 "object",这是 1995 年实现时的遗留问题,后来因为会破坏大量存量网页,一直没改。
typeof undefined; // "undefined"
typeof null; // "object" ← 坑在这里
所以要判断 null 只能用 === null,别用 typeof。
注意:
typeof notDeclared返回"undefined"不报错,而直接写notDeclared会抛 ReferenceError。判断一个可能未声明的变量时,用typeof x === 'undefined'更安全。
第三步:把 == 和 === 的结果背下来
这一步要解决比较运算的混乱。null == undefined 为 true(宽松相等里两者互等且只与彼此相等),null === undefined 为 false(类型不同)。
容易错的是和数字比较:
null == 0; // false
null >= 0; // true ← 关系运算会转数字:Number(null) === 0
undefined >= 0; // false ← Number(undefined) 是 NaN
Number(null); // 0
Number(undefined); // NaN
null == 0 是 false 而 null >= 0 是 true,就是因为 == 有专门规则,而 >= 走的是 ToNumber 转换。
第四步:认清楚两者各自出现的场景
这一步帮你建立“看到 undefined 就该怀疑漏了点什么”的条件反射。undefined 的常见来源:变量声明未赋值、函数没有 return、调用函数时少传参数、访问对象不存在的属性、delete 掉属性后再访问、稀疏数组的空位。
null 的常见来源:document.getElementById() 找不到元素、querySelector 匹配失败、正则 match 无结果、Object.getPrototypeOf(Object.prototype) 原型链顶端、以及你自己写的“清空”逻辑。
第五步:默认值、可选链、JSON 的行为差异
这一步要拿到最容易在业务里翻车的三个点。
第一,默认参数和解构默认值只对 undefined 生效:
function f(x = 1) { return x; }
f(undefined); // 1
f(null); // null ← 不触发默认值
const { a = 1 } = { a: null }; // a 是 null,不是 1
第二,?. 对两者都短路,?? 只在 null/undefined 时取右边:
0 || 'default'; // 'default' ← 0 被当成假值,通常不是你想要的
0 ?? 'default'; // 0 ← 只在 null/undefined 时兜底
第三,JSON.stringify 不认 undefined:对象里的 undefined 属性会被直接丢掉,数组里的 undefined 会变成 null,而 null 会被正常序列化成 "null"。
JSON.stringify({ a: undefined, b: null }); // '{"b":null}'
JSON.stringify([undefined, null]); // '[null,null]'
注意:接口传参时如果把 undefined 塞进对象再 JSON 序列化,这个字段会凭空消失,后端可能报“缺少必填字段”。需要保留空字段就显式传 null。
第六步:写出规范的判断代码
这一步把前面的结论落成可用写法:判断 undefined 用 x === undefined 或 typeof x === 'undefined'(后者可防未声明);判断 null 用 x === null;同时判两者用 x == null,这是宽松相等少数值得用的场景。
if (x == null) { /* null 和 undefined 都会进来 */ }
if (x === undefined) { /* 只判 undefined */ }
小结
- undefined 是引擎给的“还没值”,null 是开发者写的“值为空”。
typeof null === 'object'是历史遗留,判断 null 只能=== null。null == undefined为 true,null === undefined为 false,null >= 0为 true 但null == 0为 false。- 默认参数、解构默认值只认 undefined,不认 null。
- 兜底用
??而不是||,否则 0、空字符串会被误伤。 - JSON 序列化会丢掉 undefined 属性,需要保留字段就传 null。
- 变量初始化建议用 null,别手写
= undefined。
转载请注明出处,版权归原作者所有。