Javascript实现继承

2020-06-29 作者:伊人独憔悴

     继承(Inheritance)是一种在新对象上复用现有对象的属性的形式。这有助于避免重复操作。在JavaScript中,继承原理与其他面向对象语言有些不同。我们通过三步操作来看一下如何实现继承。

1、用函数的“原型对象”实现继承,如【清单-1】,程序执行后,三个日志全部打印了出来,这说明Woman继承自Person,wman既是Person又是Woman,同时wman也有sing方法,证明这样实现了继承。

  1. /*
  2. 清单-1
  3. */
  4. function Person(){}
  5. Person.prototype.sing = function(){};
  6. function Woman(){}
  7. //通过将Woman的原型对象赋值为Person的实例,实现继承Person
  8. Woman.prototype = new Person();
  9. const wman = new Woman();
  10. if(wman instanceof Woman)
  11.   console.log("wman is a instance of Woman");
  12. if(wman instanceof Person)
  13. console.log("wman is a instance of Person");
  14. if(typeof wman.sing === "function")
  15. console.log("wman can sing!");

2、在清单-1的14行打个断点调试一下,通过调试的方法深入研究一下继承究竟是怎么实现的。如图-1


【图-1】

3、我们将图-1中1、2、3 的关系用图的方式表现一下,如图-2:


【图-2】

从图-2可以看出
1)Woman是包含了Person(Prototype : Person),可以理解为继承了Person。
2)wman是Woman的对象(wman : Woman),wman包含了Person(proto : Person),可以理解为wman也是Person的对象。

【总结】
这里我们用函数的“原型对象”和对象的“原型链”实现了“继承”,注意原型对象(prototype)和原型(proto)不是一个概念,通过图-1和图-2都可以看出。不过这里有wman.constructor 不指向Woman 而是指向了person,就不能通过new wman.constructor()创建Woman对象了。

针对总结中出现的问题,通过修改属性的方式,将constructor指向Woman,修改代码如【清单-2】。

  1. /*
  2. 清单-1
  3. */
  4. function Person(){}
  5. Person.prototype.sing = function(){};
  6. function Woman(){}
  7. //通过将Woman的原型对象赋值为Person的实例,实现继承Person
  8. Woman.prototype = new Person();
  9. const wman = new Woman();
  10. if(wman instanceof Woman)
  11.   console.log("wman is a instance of Woman");
  12. if(wman instanceof Person)
  13. console.log("wman is a instance of Person");
  14. if(typeof wman.sing === "function")
  15. console.log("wman can sing!");
  16. //定义一个新的不可枚举的constructor属性,属性值为Woman
  17. Object.defineProperty(Woman.prototype, "constructor", {
  18.  enumerable: false,
  19.  value: Woman,
  20.  writable: true
  21. });
  22. if(wman.constructor == Woman)
  23. console.log("wman's constructor is Woman")