JavaScript原型链的终点表面是null,实际承载继承能力的是Object.prototype;前者是表示“无上级原型”的终止信号,后者是提供toString等基础方法的最后一个对象。

JavaScript 原型链的终点,表面看是 null,实际承载继承能力的终点是 Object.prototype。两者分工明确:Object.prototype 是最后一个“有行为”的对象,而 null 是它身后的终止信号——不是链上的一员,而是告诉引擎“别再往上找了”。
Object.prototype 是真正的继承终点
几乎所有普通对象({}、[]、new Date()、函数等)的原型链最终都会抵达 Object.prototype。它提供了 toString()、hasOwnProperty()、isPrototypeOf() 等基础方法,是整个对象体系的行为基石。
-
{}→Object.prototype→null -
[]→Array.prototype→Object.prototype→null -
function() {}→Function.prototype→Object.prototype→null
你可以验证:Object.getPrototypeOf({}) === Object.prototype 返回 true;而 Object.getPrototypeOf(Object.prototype) 返回 null —— 这正是规范定义的边界。
null 是设计出来的终止符,不是链上的对象
null 是原始值,不是对象,也没有自己的原型。它不能调用任何方法(null.toString() 会报错),也不能被设置为其他对象的原型(Object.setPrototypeOf(null, {}) 抛出 TypeError)。它的唯一作用,是在 Object.prototype.__proto__ 中作为显式标记:
立即学习“Java免费学习笔记(深入)”;
- 表示“此处无上级原型”,让属性查找逻辑能以
O(1)判断结束 - 物理切断循环可能(如误设
A.__proto__ = B; B.__proto__ = A) - 区分语义:
undefined是“没找到值”,null是“根本没地方可找”
为什么不能用 Object.prototype 自己当终点?
如果把 Object.prototype 当作终点,而不让它指向 null,就会面临逻辑困境:
- 它的
__proto__应该是什么?若设为undefined,引擎无法可靠判断“是否到头”,因为属性访问本身也返回undefined - 若让它指向自身或别的对象,会引发无限递归或破坏继承一致性
- null 是唯一既“非对象”又“不参与运算”的值,完美承担哨兵角色
ECMAScript 规范明确要求:Object.prototype[[Prototype]] 必须为 null(§10.2.2),这是语言稳定运行的底层契约。
主动利用这个结构:创建真正干净的对象
当你需要一个不带任何默认方法的对象(比如做纯键值映射、防污染配置),可以用:
-
Object.create(null):生成的对象直接以null为原型,跳过Object.prototype - 对比:
{}有toString、hasOwnProperty;Object.create(null)什么都没有 - 原生
Map、Set内部也采用类似思路,确保行为纯粹、内存轻量
这种用法依赖的,正是 null 作为原型链起点/终点的可控性。


















