javascript引擎将class编译为函数和原型操作:静态方法挂载在构造函数自身(如constructor.method=fn),this指向构造函数,不参与原型链查找;实例方法挂载在constructor.prototype上,this指向调用实例,通过原型链共享。

JavaScript 引擎在解析 class 时,并不真正创建“类对象”,而是将其编译为等效的函数和原型操作。静态方法和实例方法的底层结构差异,核心在于**它们被挂载的位置不同、可访问的 this 指向不同、以及是否参与原型链查找**。
静态方法:直接挂在构造函数对象自身上
引擎将 static method() { ... } 编译为类似 Constructor.method = function() { ... } 的赋值操作。它属于构造函数这个函数对象自身的属性,不进入原型链,也不被实例继承。
- 调用路径:
MyClass.staticMethod()→ 直接读取函数对象的自有属性 -
this指向:MyClass本身(不是实例,也不是undefined) - 不可通过
new MyClass().staticMethod()访问,实例上查不到该属性 - 子类能继承静态方法,是因为子类构造函数的
[[Prototype]]指向父类构造函数(即SubClass.__proto__ === ParentClass),所以能沿函数对象的隐式原型链向上查找
实例方法:自动挂载到原型对象上
引擎把类体中定义的非 static 方法(如 showSth() { ... })编译为对 Constructor.prototype 的属性赋值,等价于 Constructor.prototype.showSth = function() { ... }。
- 调用路径:
inst.showSth()→ 实例内部[[Prototype]]指向Constructor.prototype,再查找到该方法 -
this指向:调用时的实际实例对象(即inst) - 所有实例共享同一份方法,节省内存
- 可通过
Object.getPrototypeOf(inst) === MyClass.prototype验证其原型归属
关键结构对比表(运行时真实状态)
以 class Computer { constructor(n) { this.name = n; } show() {} static info() {} } 为例:
-
构造函数对象
Computer:是一个函数,自身有.info属性(静态方法),其.prototype是一个对象 -
Computer.prototype:包含.constructor和.show,是所有new Computer()实例的[[Prototype]] -
实例
const c = new Computer('Mac'):自有属性只有c.name;c.show不存在于自身,但可通过原型链访问;c.info完全不可访问
为什么不能在实例上调用静态方法?
因为引擎在方法查找时只走原型链([[Get]] 内部算法),而静态方法不在原型链上。实例的 [[Prototype]] 是 Computer.prototype,不是 Computer 函数本身;它的上一级是 Function.prototype,再往上才是 Object.prototype——整个链条里不包含 Computer 这个函数对象。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











