实现一个寄生式组合继承
function inheritPrototype(Sub, Super) {
// 创建 Super.prototype 的副本
const prototype = Object.create(Super.prototype);
// 设置 Sub.prototype 为 Super.prototype 的副本
Sub.prototype = prototype;
// 修正 constructor 指向
Sub.prototype.constructor = Sub;
}
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
};
function SubType(name, age) {
// 继承属性
SuperType.call(this, name);
this.age = age;
}
// 继承方法
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function() {
console.log(this.age);
};
let instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.log(instance1.colors); // ["red", "blue", "green", "black"]
instance1.sayName(); // Nicholas
instance1.sayAge(); // 29
let instance2 = new SubType("Greg", 27);
console.log(instance2.colors); // ["red", "blue", "green"]
instance2.sayName(); // Greg
instance2.sayAge(); // 27
解释:
-
inheritPrototype(Sub, Super)
函数: 这是核心函数,实现了原型继承。Object.create(Super.prototype)
: 创建一个以Super.prototype
为原型的新的空对象。这保证了SubType
的原型对象是SuperType
原型对象的一个副本,而不是直接引用。这样修改SubType
的原型不会影响到SuperType
的原型。Sub.prototype = prototype
: 将新创建的对象赋值给Sub.prototype
,实现原型继承。Sub.prototype.constructor = Sub
: 修正构造函数的指向。因为将Sub.prototype
覆盖了,所以需要将constructor
指回Sub
。
-
SuperType
构造函数: 定义父类型,包含属性name
和colors
。 -
SuperType.prototype.sayName
: 定义父类型原型上的方法。 -
SubType
构造函数: 定义子类型。SuperType.call(this, name)
: 调用父类型的构造函数,将this
指向子类型的实例,并传递参数name
。这实现了属性的继承。this.age = age
: 添加子类型特有的属性age
。
-
inheritPrototype(SubType, SuperType)
: 调用核心函数,实现原型继承。 -
SubType.prototype.sayAge
: 定义子类型原型上的方法。 -
实例化和测试: 创建两个实例
instance1
和instance2
,验证属性和方法的继承以及原型链的独立性。instance1
修改colors
数组不会影响instance2
,证明了每个实例都有自己的属性副本。
寄生式组合继承的优点:
- 高效: 只调用一次父类型的构造函数,避免了在原型链上创建不必要的父类型实例。
- 正确性: 解决了原型链继承和构造函数继承各自的缺点,实现了属性和方法的正确继承。
这个例子清晰地展示了寄生式组合继承的实现过程,并通过测试用例验证了其有效性。 它比其他继承方式更加高效且不易出错,因此在实际开发中被广泛采用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)