实现一个寄生式组合继承

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


解释:

  1. 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
  2. SuperType 构造函数: 定义父类型,包含属性 namecolors

  3. SuperType.prototype.sayName: 定义父类型原型上的方法。

  4. SubType 构造函数: 定义子类型。

    • SuperType.call(this, name): 调用父类型的构造函数,将 this 指向子类型的实例,并传递参数 name。这实现了属性的继承。
    • this.age = age: 添加子类型特有的属性 age
  5. inheritPrototype(SubType, SuperType): 调用核心函数,实现原型继承。

  6. SubType.prototype.sayAge: 定义子类型原型上的方法。

  7. 实例化和测试: 创建两个实例 instance1instance2,验证属性和方法的继承以及原型链的独立性。instance1 修改 colors 数组不会影响 instance2,证明了每个实例都有自己的属性副本。

寄生式组合继承的优点:

  • 高效: 只调用一次父类型的构造函数,避免了在原型链上创建不必要的父类型实例。
  • 正确性: 解决了原型链继承和构造函数继承各自的缺点,实现了属性和方法的正确继承。

这个例子清晰地展示了寄生式组合继承的实现过程,并通过测试用例验证了其有效性。 它比其他继承方式更加高效且不易出错,因此在实际开发中被广泛采用。

posted @   王铁柱6  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示