ECMAScript的组合继承


题外话:

只有自己尝试写个框架,才有机会接触像原型、作用域、事件代理、缓存系统、定时器等深层知识。

司徒正美《JavaScript框架设计》

起源

单独使用原型链继承:

  1. 优点,利用prototype实现了数据的共享,以此来实现继承。
  2. 缺点,当涉及到引用类型(比如说数组)的时候,一个实例修改了引用类型的值会影响到另一个实例,耦合性太强。

单独借用构造函数继承:

  1. 优点,子类可以向超类传参数。
  2. 缺点,方法都是在构造函数里定义的,无可复用性。

为此,才出现了组合继承

基本概念

组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。

实现思路

使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。

//console控制台验证  //构造函数实现实例属性,构造函数的优点 function SuperType(name) {     this.name = name;     this.numbers = [1,2,3]; }  //原型来定义方法,原型链的优点 SuperType.prototype.sayName = function () {     alert(this.name); };  function SubType (name, age) {      //继承属性     SuperType.call(this, name);      this.age = age; }  //继承方法 SubType.prototype = new SuperType();  //子类新定义的方法一定要在上面的继承代码之后,要不然新写的方法就没了 SubType.prototype.sayAge = function () {     alert(this.age); }  var instance1 = new SubType("MirrorAvatar", 3); instance1.numbers.push(33); instance1.numbers;  // "[1,2,3,33]" instance1.sayName();  //MirrorAvatar instance1.sayAge();  //3  var instance2 = new SubType("Cindy", 4); instance2.numbers;  //"[1,2,3]" instance2.sayName();  //Cindy instance2.sayAge();  //4

 

总结

组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JavaScript中最常用的继承模式。而且,instanceof和isPrototypeOf()也能够用于识别基于组合继承创建的对象。


发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>