ES6类继承中静态属性“被无缝传递”实为基于构造函数__proto__链的查找机制,子类访问未定义的静态属性时沿__proto__向上查找父类构造函数,而非自动复制;该机制与实例方法的prototype链查找并行独立。

ES6 类继承中,静态属性“被无缝传递”其实不是真正意义上的自动复制,而是一种基于构造函数 __proto__ 链 的查找机制——子类在访问静态属性时,若自身没有定义,就会沿着构造函数的 __proto__ 向上找父类构造函数,直到找到或到达 Function.prototype。这和实例方法靠 prototype 链查找是两套并行路径。
静态属性的继承不依赖赋值,而是靠构造函数链
当你写 class Child extends Parent,JavaScript 引擎会自动设置:
-
Child.__proto__ === Parent(子类构造函数的原型指向父类构造函数) -
Child.prototype.__proto__ === Parent.prototype(子类原型的原型指向父类原型)
静态属性定义在构造函数本身(如 Parent.VERSION = '1.0'),所以 Child.VERSION 能读到,是因为引擎查 Child.VERSION → Child.__proto__.VERSION → Parent.VERSION。
它“无缝”但有边界:只对可枚举、非私有、非方法体内的静态声明有效
以下情况不会被继承:
- 私有静态字段(
static #secret = 42)——子类完全不可见 - 在构造函数或静态块中动态赋值的变量(如
Parent.init = () => {...}之后才挂载的)——继承发生在类声明阶段,晚于该赋值则不纳入初始链 - 使用
Object.defineProperty(Parent, 'x', { value: 1, writable: false })定义的不可枚举静态属性——默认不可遍历,也不参与常规属性访问链
子类可以覆盖,也可以用 super 访问父级版本
在子类静态方法内部,super 指向父类构造函数,因此可以直接调用父类静态逻辑:
class Parent { static flag = 'base'; }
class Child extends Parent {
static getFlag() { return super.flag; } // ✅ 正确,返回 'base'
}
如果子类自己定义了同名静态属性,就会遮蔽父类版本;未定义时才触发向上查找——这种“按需委托”的行为,才是所谓“无缝”的实质。
它不复杂,但容易忽略构造函数链与实例原型链的根本分离。











