
JavaScript原型继承不是“模拟类”,而是直接建在内存对象模型之上的原生机制——它没有底座级抽象层,原型链就是它的物理架构本身。所谓“class的无缝演进”,本质是语法外壳逐步收敛对同一套底层内存行为的表达方式,而非引入新机制。
原型链即对象内存寻址路径
每个JS对象在内存中都携带一个隐式指针([[Prototype]]),指向另一个对象。这个指针不存储数据,只提供查找跳转能力。当访问 obj.method() 时,引擎执行的是:
- 检查 obj 自身内存块是否存在 method 属性;
- 若无,按 [[Prototype]] 指针加载其指向对象的内存页;
- 在该页内重复查找,直到抵达 Object.prototype(其 [[Prototype]] 为 null,即内存边界)。
这整个过程等效于C语言中结构体嵌套指针的逐级解引用,是纯粹的、不可绕过的内存遍历行为——不是“模拟继承”,而是对象间天然的、线性的内存拓扑关系。
function.prototype 是共享方法的静态内存段
构造函数的 prototype 属性,本质是一个被所有实例共用的只读内存区域地址。例如:
立即学习“Java免费学习笔记(深入)”;
function Person(name) { this.name = name; }
Person.prototype.say = function() { return this.name; };
const a = new Person('Alice');
const b = new Person('Bob');
此时 a.say 和 b.say 实际指向同一段内存中的函数代码,且 a.__proto__ 与 b.__proto__ 都等于 Person.prototype。这并非运行时动态代理,而是实例创建时就固化下来的内存映射关系——就像多个进程映射同一段共享库。
class 关键字只是原型链操作的指令集封装
ES6 的 class 并未改变任何内存布局规则:
-
class A {}→ 编译为带 prototype 属性的函数,且该函数不可直接调用; -
extends B→ 自动生成A.prototype = Object.create(B.prototype)并修正 constructor; -
super()→ 实质是沿 [[Prototype]] 向上定位到父构造函数并绑定 this 执行。
所有这些,都是对已有原型链操作的标准化汇编指令。V8 引擎内部并不识别 “class” 这个概念,它只执行 setPrototypeOf、call、defineProperty 等底层操作——class 是人类可读的原型链汇编语言。
继承的本质是原型指针的单向链式委托
JavaScript 中不存在“类的实例化”或“类型继承”这类抽象概念。所谓“继承”,仅表示:某个对象在属性缺失时,自动将查找请求委托给另一个确定的对象。这种委托完全由 [[Prototype]] 指针决定,不涉及类型系统、虚函数表或元数据反射。
因此,instanceof 的实现就是沿着 [[Prototype]] 一路比对是否等于某构造函数的 prototype——它不是类型检查,而是内存地址链路匹配;Object.getPrototypeOf(obj) 返回的也不是“类型”,而是下一个内存跳转目标。


















