null是原型链的终止标记,引擎查找到null即停止并返回undefined;它不是对象、不参与继承、不可调用方法,Object.prototype的[[Prototype]]被规范设为null以确保链终结可靠。

JavaScript 原型链查找到 null,不是“找不到就崩了”,而是引擎按明确规则一层层向上找,直到遇到 null 这个信号,主动停手、返回 undefined。它本质是一个终止标记,不是某个对象,也不参与继承。
属性查找是逐级“问上级”的过程
当你访问 obj.method(),JS 引擎实际执行的是:
- 先查
obj自身有没有method - 没有?就去
obj.__proto__上找 - 还没找到?再查
obj.__proto__.__proto__ - 一直查,直到某一级的
__proto__是null,立刻停止,返回undefined
例如:let arr = []; 调用 arr.toString(),路径是:arr → Array.prototype → Object.prototype → null,而 toString 就在 Object.prototype 上。
null 是设计出来的“停止键”,不是终点对象
null 本身不是对象,不能调方法,也没有原型:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
-
typeof null返回"object"是历史 bug,不代表它是对象 -
Object.getPrototypeOf(null)会直接报错 TypeError -
null.toString()同样报错——因为它压根不在原型链上“走” - 真正承载通用方法(如
toString、hasOwnProperty)的是Object.prototype,它的[[Prototype]]内部值被规范设为null
为什么非得是 null,不能是 undefined 或循环回自身?
选 null 是为了语义清晰、行为可靠:
- 如果终点是
undefined,那属性访问返回undefined就无法区分“真没找到”和“链到头了” - 如果
Object.prototype.__proto__指向自己,就会无限循环,引擎根本停不下来 -
null是原始值,不可修改、不可扩展,作为哨兵值稳定且无副作用
可以动手验证这条链的终点
运行这几行就能看到真实结构:
let obj = {};console.log(obj.__proto__ === Object.prototype); // trueconsole.log(Object.getPrototypeOf(Object.prototype)); // nullconsole.log(Object.prototype.__proto__); // null
所有普通对象、数组、函数……最终都会汇入 Object.prototype,而它的上一级就是 null —— 这条链到这里,就干净利落地结束了。

















