es6 class本质是原型链的语法糖,b.__proto__===a、b.prototype.__proto__===a.prototype、new b().__proto__===b.prototype构成三层继承链。

ES6 的 class 本质仍是基于原型链的语法糖,它底层依然通过 __proto__ 和 prototype 实现继承关系,只是把显式的原型操作封装得更简洁。关键在于:子类的 __proto__ 指向父类构造函数,而子类实例的 __proto__ 指向子类的 prototype;同时子类 prototype.__proto__ 指向父类 prototype,从而构成方法查找的原型链。
class 继承中 `__proto__` 的三层关键指向
以 class B extends A 为例,有三个核心原型链接:
-
B.__proto__ === A:子类构造函数的
__proto__直接继承父类构造函数(实现静态方法/属性的继承,如A.foo()可被B.foo()访问) -
B.prototype.__proto__ === A.prototype:子类原型对象的
__proto__指向父类原型对象(实现实例方法的继承,如new B().method()能调用A.prototype.method) -
new B().__proto__ === B.prototype:实例的
__proto__指向子类原型(这是所有构造函数实例的标准行为)
`extends` 如何自动设置这些 `__proto__` 关系
当你写 class B extends A,JavaScript 引擎会隐式执行类似以下逻辑(简化示意):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 创建
B.prototype对象,并设其__proto__为A.prototype(即Object.setPrototypeOf(B.prototype, A.prototype)) - 设
B.__proto__为A(即Object.setPrototypeOf(B, A)),使子类可继承父类的静态成员 - 确保
B构造函数内部必须调用super(),否则无法初始化this——因为super()实际调用的是A构造函数,并将新对象的__proto__正确关联到B.prototype
手动模拟 class 继承的 `__proto__` 链路(ES5 风格)
下面代码等价于 class B extends A 的原型连接效果:
function A() {}
A.prototype.a = function() { return 'from A'; };
A.staticMethod = () => 'A static';
function B() {
A.call(this); // 等效 super()
}
// 关键三步设置 __proto__
Object.setPrototypeOf(B, A); // B.__proto__ → A
Object.setPrototypeOf(B.prototype, A.prototype); // B.prototype.__proto__ → A.prototype
B.prototype.b = function() { return 'from B'; };
// 验证
console.log(new B().__proto__ === B.prototype); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(B.__proto__ === A); // true
console.log(new B().a()); // 'from A'(沿 B.prototype → A.prototype 查找)
console.log(B.staticMethod()); // 'A static'(沿 B → A 查找)
注意 `__proto__` 不是标准推荐的直接操作方式
__proto__ 是非标准但广泛支持的访问器,现代代码应优先使用 Object.getPrototypeOf() 和 Object.setPrototypeOf()。ES6 class 的设计屏蔽了这些细节,但理解其背后的 __proto__ 链,有助于调试继承失效、方法找不到或 this 绑定异常等问题。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










