null是语义明确的“空对象引用”,但行为反直觉:typeof返回"object"是历史漏洞;需用x===null识别;语义为“存在且明确为空”,与undefined严格区分;不参与原型链,不可调用方法。
javascript 中的 null 不是“普通值”,而是一个有明确语义、但行为处处反直觉的边界类型。它被设计为“空对象引用”,却不是对象;它在类型判断中被 typeof 错判为 "object";它能被安全存储,却不能作为键;它语义清晰,却被大量误用为 undefined 的替代品。
typeof null 返回 "object" 是历史漏洞,不是设计意图
这是 JS 最著名的陷阱之一:引擎底层将 null 表示为全零内存地址,而早期 typeof 实现直接检查对象标志位——结果把 null 当作了“空对象”。它不表示任何对象实例,也不具备对象行为(如调用方法会报错)。
- 永远不要用
typeof x === "object"判断是否为对象,因为它会把null也包含进来 - 正确判断对象类型应使用
Object.prototype.toString.call(x) === "[object Object]" - 若需单独识别
null,唯一可靠方式是x === null
null 在 API 和缓存中的语义必须严格区分
null 的核心语义是:字段存在,但业务上确实无值。它不是“没传”或“没定义”,而是“传了,且明确为空”。
- 后端返回
{"user": null}应理解为“用户信息已查询,确认不存在”,而非“接口出错”或“字段缺失” - 在 LRU 缓存中,
cache.set("key", null)是合法操作,表示“缓存该键,值为空”;而cache.set("key", undefined)等价于删除该键 - 前端消费时,
response.user === null可触发“用户未注册”逻辑;response.user === undefined则应视为数据结构异常或字段未返回
null 不能参与原型链,也不是继承终点
虽然原型链最终以 null 结束,但它本身不是链上成员,只是引擎用于终止查找的哨兵值。
-
Object.getPrototypeOf(Object.prototype)返回null,表明继承到此为止 -
Object.getPrototypeOf(null)直接抛错——null没有 [[Prototype]],不可被设为任何对象的原型 -
null无法调用任何方法:null.toString()报错,String(null)才能得到"null"
null 与 undefined 的混合使用极易引发隐性 bug
二者虽在 == 下相等,但语义完全对立:
立即学习“Java免费学习笔记(深入)”;
-
undefined是“未初始化、未定义、属性不存在”的自然状态;null是“已声明、已赋值、主动清空”的人工状态 - 解构赋值默认值只对
undefined生效:const { name = "guest" } = { name: null }→name仍为null - 函数参数检测应优先用
arg === undefined,而非!arg,否则0、false、""全部被误拦截


















