JavaScript 的 class 继承本质是原型链机制,ES6 class 仅为语法糖;extends 通过 Object.setPrototypeOf(Dog.prototype, Animal.prototype) 设置原型继承,super() 等价于 Animal.call(this, ...),static 方法则通过构造函数的 [[Prototype]] 链继承。

JavaScript 中的 class 继承看似像 Java 或 C++ 那样基于类,但底层完全不涉及“类”的实体,而是通过原型链(prototype chain)实现的。ES6 的 class 只是语法糖,编译后仍会转为构造函数 + 原型操作。
class 定义实际生成构造函数和 prototype
当你写:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
bark() {
console.log(`${this.name} barks.`);
}
}
引擎内部等价于定义了两个构造函数,并手动设置原型关系:
-
Dog.prototype.__proto__被设为Animal.prototype(不是new Animal(),而是直接指向父类原型对象) -
Dog.prototype.constructor被修正回Dog(否则会继承自Animal) -
super()在子类构造器中,本质是调用Animal.call(this, ...),确保父类实例属性正确挂载到this
原型链查找保障方法可继承
创建实例后,方法调用依赖原型链查找:
立即学习“Java免费学习笔记(深入)”;
const d = new Dog('Leo')-
d.bark()→ 找到Dog.prototype.bark -
d.speak()→Dog.prototype上没有,沿__proto__查到Animal.prototype.speak -
d.toString()→ 继续向上到Object.prototype.toString
整条链是:d → Dog.prototype → Animal.prototype → Object.prototype → null
extends 本质是 Object.setPrototypeOf(Dog.prototype, Animal.prototype)
ES6 规范要求 extends 必须让子类原型对象的 [[Prototype]] 指向父类原型对象。这一步不能用赋值 Dog.prototype = Object.create(Animal.prototype) 实现(那样会丢失 constructor),而必须用 Object.setPrototypeOf() 动态设置隐式原型。
- 这是为了保持
Dog.prototype仍是函数对象(有constructor、__proto__等),同时又能继承父类方法 - 如果手动改写
Dog.prototype = {...},就会切断与Animal.prototype的连接,导致继承失效
static 方法不走原型链,而是挂在构造函数本身
static 成员属于类(即构造函数)自身,不是实例或原型链的一部分:
-
Dog.create()直接在Dog函数上查找,不涉及__proto__ -
Dog.__proto__ === Animal—— 这才是静态继承的路径:子类构造函数的[[Prototype]]指向父类构造函数 - 所以
Animal的 static 方法也能被Dog直接调用(如Dog.animalMethod())


















