javascript中的“伪类”是用构造函数+prototype模拟类行为的设计模式,本质仍是基于原型;其继承通过替换子类prototype为父类实例实现,但存在引用属性共享、无法传参等缺陷,常用组合继承改良。

JavaScript 中的“伪类”不是真正的类,而是用构造函数 + prototype 模拟类行为的设计模式。它不改变语言基于原型的本质,只是让写法更贴近传统面向对象语言,便于理解与协作。关键在于:**用构造函数定义实例属性,靠原型链共享方法,并通过显式原型替换建立继承关系**。
伪类继承的核心机制
伪类继承依赖两个基本动作:
- 定义子构造函数(如
function Cat() {...}),负责初始化实例自有属性 - 将子构造函数的
prototype替换为父构造函数的一个实例(如Cat.prototype = new Mammal()),从而把父类原型上的方法和属性“链入”子类原型
此时,new Cat() 创建的对象会沿着原型链向上找到 Mammal.prototype 上的方法,实现行为复用。
为什么叫“伪”?—— 它的典型缺陷
“伪”字体现在它表面像类继承,实则暴露原型本质带来的副作用:
-
共享引用类型属性:若父类构造函数中初始化了数组、对象等引用值(如
this.colors = ['red']),所有子类实例会共用同一份内存,修改一个会影响全部 -
无法向父构造函数传参:因为
Cat.prototype = new Mammal()是在定义阶段执行的,此时无法根据每个Cat实例的参数动态调用Mammal -
constructor 指针丢失:替换原型后,
Cat.prototype.constructor指向Mammal,需手动修正为Cat
常用改良方案:组合继承
为兼顾实例隔离与方法复用,实践中普遍采用“组合继承”——融合原型链继承与构造函数借用:
- 在子构造函数内部用
Parent.call(this, ...)调用父构造函数,确保每个实例拥有独立属性(解决共享问题) - 同时仍用
Child.prototype = new Parent()建立原型链,复用父类方法(保留继承链) - 最后补上
Child.prototype.constructor = Child,修复构造器指向
这是 ES6 class 出现前最稳健的伪类继承实践,平衡了可读性、安全性与兼容性。
现代替代:class 是语法糖,但底层仍是伪类逻辑
class 关键字并未改变 JavaScript 的原型本质。它只是把上述组合继承流程封装得更简洁:
-
extends底层仍通过Object.setPrototypeOf(Child.prototype, Parent.prototype)和构造函数调用模拟原型链 -
super()在子构造函数中,实际就是Parent.call(this, ...)的封装 - 所有
class定义的方法仍被添加到原型上,而非实例上
所以,“伪类”思维没有过时,只是被隐藏得更好;理解它,才能真正看懂 class 报错、instanceof 判定或调试原型链时发生了什么。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











