class 是原型链的语法糖,其构造函数的 prototype 可动态修改,实例的 [[prototype]] 链全程可干预,静态方法同样遵循原型委托机制,动态性与传统函数模式完全一致。

Class 和原型链在 JavaScript 中不是对立关系,而是同一套机制的两种表达方式——class 是原型链的语法糖,动态性天然共存,关键在于理解“语法封装”不等于“能力封禁”。
Class 本身仍是可动态修改的原型对象
class 声明生成的构造函数,其 prototype 属性仍是普通对象,和传统构造函数完全一样。你随时可以往上面添加、删除或覆盖方法,所有已有实例立刻生效。
-
class Cat { constructor(name) { this.name = name; } }创建后,Cat.prototype.meow = function() { console.log('meow!'); }立刻让所有new Cat()实例可用 - 甚至可以直接替换整个
Cat.prototype = { ... }(注意重设constructor),旧实例的__proto__会自动指向新原型 - 这种运行时增强能力,和
function Cat(){}模式毫无区别
实例的 [[Prototype]] 链全程可干预
无论用 new class 还是 new Function 创建实例,其内部 [[Prototype]] 都是可读写链接,不受 class 语法限制。
-
const c = new Cat('Miao');之后执行Object.setPrototypeOf(c, { purr() { return 'purr~'; } });,c.purr()立刻可用 - 子类实例的原型链也保持开放:
class Lion extends Cat {}后,Lion.prototype.__proto__ === Cat.prototype为真,你可以直接操作Cat.prototype影响所有Lion实例 - 甚至能用
Object.setPrototypeOf(c, null)切断继承,让对象变成“纯字典”,class 不构成任何阻碍
静态成员与实例行为同样遵循原型查找逻辑
class 的静态方法不是“脱离原型链的特殊存在”,它走的是构造函数自身的 [[Prototype]] 查找路径,本质仍是原型委托。
-
class A { static foo() {} }中,A.foo()查找顺序是:A → A.[[Prototype]](即Function.prototype)→ … -
class B extends A {}后,B.foo()能调用是因为B.[[Prototype]] === A,这和实例的instanceof判定共享同一套链式查找机制 - 你完全可以动态给
A添加静态方法:A.bar = () => 'bar',B.bar()随即可用
混用时需留意的细节而非障碍
动态性共存没问题,但 class 的一些默认行为(如方法不可枚举、TDZ)和手动原型操作习惯略有差异,稍作适配即可无缝协作。
- class 内定义的方法默认
enumerable: false,而手写Obj.prototype.m = function(){}默认为true;若需一致,可用Object.defineProperty显式设置 - class 声明不被提升,不能在声明前调用;但 prototype 修改本身无此限制,
MyClass.prototype.x = ...放在哪都行 - 继承时若手动改写
Sub.prototype,记得修复constructor,否则new Sub()实例的constructor会指向父类
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











