《JS设计模式》笔记-继承之一

类式继承

通过原型链的继承称为类式继承,原理就是将子级的prototype属性赋值成父级的实例化对象。赋值之后父级的属性和方法将全部添加到子级的原型对象中。

    function SuperClass () {
      this.name = '小明'
      this.time = '01-15'
    }
    SuperClass.prototype.getName = function () {
      console.log(this.name)
    }
    function SubClass () {
      this.age = '23'
    }
    SubClass.prototype = new SuperClass()
    var instance = new SubClass()
    instance.getName()  // 小明
    console.log(instance.age)   // 23
    console.log(instance.time)  // 01-15
    console.log(instance instanceof SubClass)   // true
    console.log(SubClass instanceof SuperClass)   // false
    console.log(SubClass.prototype instanceof SuperClass)   // true
  

这里声明,instanceof 只判断是否有实例关系,并不表示两者的继承

类式继承有两个缺点

  • 1.一个子类的实例修改,其他共同从父类原型中继承过来的属性也会改变
  • 2.由于子类实现的继承是靠其原型prototype对父类实例化的实现,因此在创建父类的时候,是无法向父类传递参数的

构造函数继承

构造函数继承的核心在SuperClass.call(this, age)。构造函数继承的缺点在于代码的复用性差。每次实例化对象时,就相当于将父类的属性和方法全都 重新创建了一遍。而且不能继承父类原型上的方法和属性。

    function SuperClass (age) {
      this.list = ['语文', '数学', '英语']
      this.age = age
    }
    SuperClass.prototype.getList = function () {
      console.log(this.list)
    }
    function SubClass (age) {
      SuperClass.call(this, age)
      this.time = '2018-01-15'
    }
    var instance = new SubClass('28')
    console.log(instance.age)   // 28
    instance.getList()    // instance.getList is not a function

组合模式

组合模式就是将类继承和构造函数继承组合起来,类继承的方法为共用,构造函数继承的方法为独立的互不影响

    function SuperClass () {
      this.name = '小明'
      this.list = ['语文', '数学', '英语']
    }
    SuperClass.prototype.getList = function () {
      console.log(this.list)
    }
    function SubClass (age) {
      this.age = age
      SuperClass.call(this, age)
    }
    SubClass.prototype = new SuperClass()

    var instance = new SubClass('31')
    console.log(instance.name)    // 小明
    console.log(instance.age)     // 31
    instance.getList()            // [ "语文", "数学", "英语" ]
  

那么这种继承方式有需要进一步优化的地方吗,有。在使用构造函数继承时执行了一遍父类的构造函数,在实现子类原型的类式继承时又执行了一遍父类的构造函数。

这句话怎么理解呢,看下面的例子

在例子中,可以明显看到,按照类式继承,父类的构造函数中的属性和方法会挂到子类的原型对象中。所以上面的继承方式中,在子类的构造函数中和子类的原型对象中 都存在父类的构造函数中的属性和方法

   function SuperClass () {
     this.name = '小明'
     this.list = ['语文', '数学', '英语']
   }
   SuperClass.prototype.getList = function () {
    console.log(this.list)
   }
   function SubClass (age) {
     this.age = age
     // SuperClass.call(this, age)
   }
   SubClass.prototype = new SuperClass()
   var instance = new SubClass()
   console.log(instance.name)
  

原型式继承

   function SuperClass () {
      this.name = '小明'
      this.list = ['语文', '数学', '英语']
    }
    SuperClass.prototype.getList = function () {
      console.log(this.list)
    }
    function SubClass (age) {
      this.age = age
      SuperClass.call(this, age)
    }
    SubClass.prototype = new SuperClass()

    var instance = new SubClass('31')
    console.log(instance.name)    // 小明
    console.log(instance.age)     // 31
    instance.getList()            // [ "语文", "数学", "英语" ]

随机浏览