object.prototype 是原型链的终点对象,其 proto 为 null;null 是终止信号而非对象,规范强制要求且不可替代。

原型链的“顶端”常被简略说成 null,但更准确地说:Object.prototype 是最后一个可访问的原型对象,而它的 __proto__(即内部 [[Prototype]])值为 null。这个 null 不是对象,不参与继承,也不提供任何方法——它只是一个终止信号。
Object.prototype 才是真正意义上的“终点对象”
所有普通对象(如 {}、[]、new Date())、函数、数组等,其原型链最终都会抵达 Object.prototype。它定义了 toString()、hasOwnProperty()、isPrototypeOf() 等通用方法,是整个对象体系的行为基础。
-
{}的原型链:{} →Object.prototype→null -
[]的原型链:[] →Array.prototype→Object.prototype→null -
function f(){}的原型链:f →Function.prototype→Object.prototype→null
null 是链的“终止符”,不是“终点对象”
null 是原始值,没有 [[Prototype]],不能调用任何方法(null.toString() 会报错),也不能被设为其他对象的原型(Object.setPrototypeOf(null, {}) 抛异常)。它只在一处合法存在:Object.prototype.__proto__。
- 引擎靠
Object.getPrototypeOf(obj) === null判断查找是否该停止 - 属性查找时,一旦走到
null还没找到,就返回undefined,不报错 - 若误让原型指向自身(如
A.__proto__ = A),null的存在能物理切断循环,避免死递归
为什么不能用 undefined 或 Object.prototype 自身作终点?
undefined 表示“未定义”,仍可参与运算(如 typeof undefined === "undefined"),语义上不表示“无上级”;而 Object.prototype 本身是一个完整对象,有属性、有方法——若把它当作终点,查找就会停在这里,无法体现“再往上真没了”的终结感。
-
Object.prototype.__proto__必须是null,这是 ECMAScript 规范硬性要求(§10.2.2) - 只有
null能实现 O(1) 终止判断:一次严格相等即可,无需类型转换或额外逻辑 - 所有标准对象都遵守这一结构,保证行为一致、容错可靠
主动利用 null 终点做轻量级隔离
当你需要一个“零继承”的干净对象(比如用作哈希表、配置容器、防污染映射),可直接以 null 为原型创建:
-
const map = Object.create(null)→ 原型链:map →null(跳过Object.prototype) - 它没有
toString、hasOwnProperty等方法,不会被for...in枚举污染 - 原生
Map、Set内部也采用类似思路,确保行为纯粹、内存精简











