欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

捋一捋js面向对象的继承问题

程序员文章站 2022-03-10 18:27:26
说到面向对象这个破玩意,曾经一度我都处于很懵逼的状态,那么面向对象究竟是什么呢?其实说白了,所谓面向对象,就是基于类这个概念,来实现封装、继承和多态的一种编程思想罢了。今天我们就来说一下这其中继承的问题。 好,先不直接上代码,而是反手来一波文字说明,捋一捋思路。 曾经一段时间因为javascript ......

  说到面向对象这个破玩意,曾经一度我都处于很懵逼的状态,那么面向对象究竟是什么呢?其实说白了,所谓面向对象,就是基于类这个概念,来实现封装、继承和多态的一种编程思想罢了。今天我们就来说一下这其中继承的问题。

  好,先不直接上代码,而是反手来一波文字说明,捋一捋思路。

  曾经一段时间因为javascript关于类实现继承的不规范,导致各种各样实现继承的代码;而实际上不管代码怎么变,继承都基于两种方式:

  1.通过原型链,即子类的原型指向父类的实例从而实现原型共享。
  2.借用构造函数,即通过js的apply、call实现子类调用父类的属性、方法;
  原型链方式可以实现所有属性方法共享,但无法做到属性、方法独享(例如son1指向的是父类实例,son2,son3同样如此,大家都是吃的同一碗饭);

  而借用构造函数除了能独享属性、方法外还能在子类构造函数中传递参数,但代码无法复用。总体而言就是可以实现所有属性方法独享,但无法做到属性、方法共享(例如,son1新增了一个函数,然后想让son2、son3一起用的话就无法实现了,只能son2,son3各自在构造函数中新增)。

  组合继承就是把以上两种继承方式一起使用,把共享的属性、方法用原型链继承实现,独享的属性、方法用借用构造函数实现,所以组合继承几乎完美实现了js的继承;
为什么说是“几乎”?因为后来人们发现组合继承有一个小bug,实现的时候调用了两次父类,性能上不合格啊有木有!怎么解决呢?于是“寄生继承”就出来了。

  寄生继承:
  简单而言,寄生继承就是不用实例化父类了,直接实例化一个临时副本实现了相同的原型链继承。(即子类的原型指向父类原型的副本),如此一来,这个问题就完美解决了。
 
  接下来是代码部分:
  捋一捋js面向对象的继承问题
 
  这里我们通过apply方法给儿子传了私有属性,但是父类原型上的方法是无法调用的。
  然后我们试试通过原型链来实现继承。
  捋一捋js面向对象的继承问题
  这样一来就把父类的全部东西都一股脑继承下来了,而且我这里如果Sons修改了父类的原型,其他跟着用的比如Daughters也要跟着遭殃。
  而组合继承这时候就出来了,组合继承就是把以上两种继承方式一起使用,把共享的属性、方法用原型链继承实现;独享的属性、方法用借用构造函数实现。至于寄生组合继承,它是为了解决组合继承会二次调用父类这个bug出现的优化方法,具体实现如下:
  捋一捋js面向对象的继承问题
  在这一步,无论是儿子还是女儿,都能成功调用父类的公用方法。接着在末尾添加两行代码往下看:
  捋一捋js面向对象的继承问题
   两个say方法虽然同名,却互不影响。最后调用父类的私有属性看看:
  捋一捋js面向对象的继承问题
  只有儿子利用私有属性拿到了secret,而女儿没有拿到,完美解决共享与独享分配的问题!