JavaScript 的 class 是原型继承的语法糖,不改变底层机制:自动挂载方法到 prototype、设置实例 __proto__、处理 extends 和 super 的原型链接,但所有操作仍可手动干预且语义等价于 ES5 原型写法。

JavaScript 的 class 语法对原型链操作的封装是**彻底而自动的,但不隐藏、不改变底层机制**——它把原本需要手动设置的原型关系、构造函数绑定、继承链连接等步骤,全部收进语法内部,开发者写起来像在定义“类”,运行时却仍是标准的原型链委托。
封装了哪些具体操作?
这些原本要手写的原型链逻辑,class 全部帮你完成:
- 自动将方法挂载到
ClassName.prototype上,无需再写Person.prototype.say = function() {...} - 自动为实例设置
__proto__指向类的prototype(即new Person().__proto__ === Person.prototype) -
extends自动执行两层链接:子类prototype.__proto__指向父类prototype,同时子类构造函数的__proto__指向父类构造函数,实现实例方法与静态方法双重继承 -
super()在子类constructor中,本质是调用父类构造函数并绑定this,等价于Parent.call(this, ...args)
没封装、也不能绕过的部分
封装再好,也不等于抽象掉原型链本身。以下关键行为依然暴露且可干预:
- 所有
class定义最终仍生成函数对象,typeof MyClass === 'function' - 你仍能直接修改
MyClass.prototype,所有已有和未来实例都会受影响 - 实例的
[[Prototype]]链完全可见,可用Object.getPrototypeOf(obj)逐级向上检查 - 没有私有字段真正阻断原型访问(
#field是语法级私有,不影响原型链结构)
为什么说它是“糖”而不是“替代”?
因为去掉 class 语法,用函数+原型方式重写,语义和行为完全一致:
立即学习“Java免费学习笔记(深入)”;
-
class A { m() {} }等价于function A() {}; A.prototype.m = function() {}; -
class B extends A等价于先定义B函数,再调用Object.setPrototypeOf(B.prototype, A.prototype)和Object.setPrototypeOf(B, A) - 哪怕用了
class,instance instanceof A的判断逻辑仍是沿着[[Prototype]]链查找A.prototype
实际开发中要注意什么?
封装带来便利,也容易掩盖关键细节:
- 不要误以为
class引入了“真类系统”——它不提供编译期类型检查、不阻止原型篡改、不改变动态委托本质 - 混用
class和Object.create()或手动__proto__设置时,需主动修复constructor指针,否则instance.constructor可能错乱 - 想做高度定制的继承(如多继承模拟、属性拦截、运行时原型切换),直接操作原型往往比套用
class更清晰可控


















