静态方法只挂载在构造函数自身,不参与实例原型链继承,调用需通过constructor.staticmethod();子类可通过__proto__链继承父类静态方法,但静态属性不会自动继承。

JavaScript 中类的静态方法不属于实例或原型链,它们只挂在构造函数自身上。所以你不能通过 instance.staticMethod() 调用,也不能靠 instance.__proto__ 或 Constructor.prototype 找到它——它根本不在那条链上。
静态方法不进原型链,是因为它压根不参与实例继承
原型链的作用是让实例对象能顺着 __proto__ 一路向上查找方法和属性。但静态方法是直接赋给构造函数的自有属性(比如 Animal.eat = function() {}),跟 Animal.prototype 完全无关。实例的原型链终点是 Object.prototype,而静态方法在 Animal 这个函数对象身上,两者不在同一条路径上。
- 调用
new Animal().eat()→ 报错:实例找不到eat - 调用
Animal.eat()→ 成功:直接访问函数对象的自有属性 - 调用
Animal.prototype.eat()→ undefined:除非你手动把它挂到 prototype 上
静态方法的“继承”靠的是构造函数之间的 __proto__ 链
使用 class Child extends Parent 时,JavaScript 自动设置 Child.__proto__ === Parent。这意味着当你写 Child.doStuff(),引擎会先查 Child 自身有没有 doStuff;没有就沿着 Child.__proto__(即 Parent)继续找——这就是静态方法“被继承”的真实机制。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 这条链是
Child → Parent → Function.prototype,和实例的__proto__链完全独立 - 子类没重写时,
Child.staticMethod()实际执行的是Parent.staticMethod() - 此时方法内的
this指向的是Child,不是Parent
静态属性不会自动继承,必须手动复制
静态方法能“查找到”,是因为函数调用时有隐式向上查找机制;但静态属性(如 Parent.VERSION = '1.0')没有这个行为——JS 不会为属性访问走 __proto__ 链。所以 Child.VERSION 是 undefined,哪怕 Child.__proto__ === Parent。
- 要让子类拥有相同静态属性,得显式赋值:
Child.VERSION = Parent.VERSION - 或者在类定义后遍历父类自有属性:
Object.getOwnPropertyNames(Parent).forEach(key => { if (typeof Parent[key] === 'function') Child[key] = Parent[key]; else Child[key] = Parent[key]; }) -
super在静态方法里只能调用父类静态方法,不能读取静态属性
Object 的静态方法为什么子类用不了
所有类的 prototype 都继承自 Object.prototype,所以实例能用 toString();但类本身(构造函数)是 Function 的实例,它的 __proto__ 指向 Function.prototype,而不是 Object。因此 MyClass.keys() 找不到 Object.keys,这不是 bug,是设计使然——避免静态命名空间污染,也保持继承语义清晰。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










