继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承的特性。
龙生龙、凤生凤、老鼠的儿子会打洞描述的正是继承的含义,分别封装中国人和日本人的行为特征来理解编程中继承的含义,代码如下:

  1. <script>
  2. // 封装中国人的行为特征
  3. function Chinese() {
  4. // 中国人的特征
  5. this.arms = 2;
  6. this.legs = 2;
  7. this.eyes = 2;
  8. this.skin = 'yellow';
  9. this.language = '中文';
  10. // 中国人的行为
  11. this.walk = function () {}
  12. this.sing = function () {}
  13. this.sleep = function () {}
  14. }
  15. // 封装日本人的行为特征
  16. function Japanese() {
  17. // 日本人的特征
  18. this.arms = 2;
  19. this.legs = 2;
  20. this.eyes = 2;
  21. this.skin = 'yellow';
  22. this.language = '日文';
  23. // 日本人的行为
  24. this.walk = function () {}
  25. this.sing = function () {}
  26. this.sleep = function () {}
  27. }
  28. </script>

其实我们都知道无论是中国人、日本人还是其它民族,人们的大部分特征是一致的,然而体现在代码中时人的相同的行为特征被重复编写了多次,代码显得十分冗余,我们可以将重复的代码抽离出来:

原型继承

通过手动修改构造函数的原型对象,来实现继承

  1. function Father() {
  2. this.money = 1000
  3. this.diaotoufa = true
  4. }
  5. let f = new Father()
  6. function Son() {
  7. this.money = 50
  8. }
  9. // 手动修改Son的原型对象(自己写了一个对象的继承关系;)
  10. Son.prototype = f
  11. let s = new Son()
  12. console.log(s.momey) // 50 // 优先调用自己的属性
  13. console.log(s.diaotoufa) // true 对象自己没有这个属性,则使用继承下来的属性

image.png

原型链

基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对象的链状结构关系称为原型链,如上图所示。
在 JavaScript 对象中包括了一个非标准备的属性 __proto__ 它指向了构造函数的原型对象,通过它可以清楚的查看原型对象的链状结构。

1.3 写在最后

面向对象(OOP)是编程时的一种指导思想,需要通过不断的实践才能体会面向对象编程的优势,在 JavaScript 中面向对象编程的实现是以构造函数和原型对象为核心的,因此掌握构造函数和原型对象的语法是灵活运用面向对象的基础。
面向对象多态的特性在 JavaScript 中应用场景相对较少,本次课中暂不讲解。