03-JavaScrpit-面向对象程序设计 - 继承

优质
小牛编辑
132浏览
2023-12-01

原型继承

  • 类与实例
    • 类的声明
    • 生成实例
  • 类与继承
    • 如何实现继承
    • 继承的几种方式

类的声明

  • 类声明 构造函数
  1. function Animal1() {
  2. this.name = 'animal';
  3. }
  • ES6中class的声明
  1. class Animal2 {
  2. constructor() {
  3. this.name = 'animal';
  4. }
  5. }

1.构造函数方式进行继承

  1. function Parent1() {
  2. this.name = 'parent1';
  3. }
  4. function Child1() {
  5. Parent1.call(this);
  6. this.type = 'child1';
  7. }
  8. console.log(new Child1());
  • 但是如果要继承原型对象上的方法是没办法继承的
  1. // 借助构造函数
  2. function Parent1() {
  3. this.name = 'parent1';
  4. }
  5. //
  6. Parent1.prototype.say = function () {
  7. console.log('say');
  8. }
  9. //但是如果要继承原型对象上的方法是没办法继承的
  10. function Child1() {
  11. Parent1.call(this);
  12. this.type = 'Child1';
  13. }
  14. console.log(new Child1());

2.借助原型链实现继承

  1. function Parent2() {
  2. this.name = 'parent2';
  3. }
  4. function Child2() {
  5. this.type = 'child2';
  6. }
  7. Child2.prototype = new Parent2();//让child2的原型赋值为Parent2的实例
  8. console.log(new Child2());
  • s1与s2之间不相互隔离
  • 原型链中共用
  1. function Parent2() {
  2. this.name = 'parent2';
  3. this.num = [1,2,3];
  4. }
  5. function Child2() {
  6. this.type = 'child2';
  7. }
  8. Child2.prototype = new Parent2();//让child2的原型赋值为Parent2的实例
  9. var s1 = new Child2();
  10. var s2 = new Child2();
  11. console.log(s1.play,s2.play);

3.组合方式

  1. function Parent3() {
  2. this.name = 'Parent3';
  3. this.play = [1,2,3];
  4. }
  5. function Child3() {
  6. Parent3.call(this);
  7. this.type = 'child3';
  8. }
  9. Child3.prototype = new Parent3();//Child3的原型对象指向Parent3的实例
  10. console.log(new child3);
  • 父类构造函数执行了多次,没有必要的重复执行

4.组合方式改进1

  1. function Parent4() {
  2. this.name = 'parent4';
  3. }
  4. function Child4() {
  5. Parent4.call(this);
  6. this.type = 'child4';
  7. }
  8. Child4.prototype = Parent4.prototype;
  9. var s5 = new Child4();
  10. var s6 = new Child4();
  11. console.log(s5,s6);
  • instanceofconstructor
  1. console.log(s5 instanceof Child4,s5 instanceof Parent4);
  • 如何区分是子类实例化的还是父类实例化的

5.组合方式改进2

  • 主要是在继承的时候让 子类的原型对象 =
    Object.Create(父类构造函数的原型对象)
  • 再通过改变子类的原型对象的constructor,因为此时的constructor的指向是父类原型对象的构造函数
  1. function Parent5() {
  2. this.name = 'Parent5';
  3. this.play = [1,2,3];
  4. }
  5. function Child5() {
  6. Parent5.call(this);
  7. this.type = 'Child5'
  8. }
  9. Child5.prototype = Object.create(Parent5.prototype);
  10. //通过Object.create()创建一个新的对象,传入的原型对象是Parent.prototype
  11. console.log('组合继承改进2',new Child5);
  12. //改变constructor的指向
  13. function Parent6() {
  14. this.name = 'Parent6';
  15. this.play = [1,2,3];
  16. }
  17. function Child6() {
  18. Parent6.call(this);
  19. this.type = 'Child6'
  20. }
  21. Child6.prototype = Object.create(Parent6.prototype);
  22. Child6.prototype.constructor = Child6;
  23. console.log('组合继承改进2-constructor',new Child6);

6.原型式继承

  1. //原型式继承
  2. function object_oop(o) {
  3. function F() {
  4. }
  5. F.prototype = o;
  6. return new F();
  7. }
  8. var person = {
  9. name:"zhangjianan",
  10. friends:["yueyue","red"]
  11. };
  12. var OnePerson = object_oop(person);
  13. console.log('原型式继承',OnePerson);
  14. OnePerson.name = "Goge";
  15. console.log('原型式继承',OnePerson);
  16. var TwoPerson = object_oop(person);
  17. TwoPerson.friends.push("red");
  18. console.log('原型式继承',OnePerson,TwoPerson);
  19. //ES5原型式继承
  20. var ThreePerson = Object.create(person,{
  21. name: {
  22. value:"XIXI"
  23. }
  24. })
  25. console.log(ThreePerson);
  26. var FourPerson = Object.create(ThreePerson,{
  27. name:{
  28. value:[1,2,3,4]
  29. }
  30. })
  31. console.log('原型式继承',FourPerson);
  • ES5中主要使用Object.create()去创建对象

贴近实际开发原型链继承的例子

  1. function Elem(id) {
  2. this.elem = document.getElementById(id);
  3. }
  4. Elem.prototype.html = function (val) {
  5. var elem = this.elem;
  6. if (val) {
  7. elem.innerHTML = val;
  8. return this; // 链式操作
  9. }else {
  10. return elem.innerHTML;
  11. }
  12. }
  13. Elem.prototype.on = function (type, fn) {
  14. var elem = this.elem ;
  15. elem.addEventListener(type, fn) ;
  16. }
  17. var div1 = new Elem('div1');
  18. //console.log(div1.html());
  19. div1.html('<p>tyrmars</p>
  20. ')
  21. div1.on('click',function () {
  22. alert('click')
  23. })

写一个原型链继承的例子

  1. //动物
  2. function Animal(){
  3. this.eat = function () {
  4. console.log('animal eat');
  5. }
  6. }
  7. //狗?
  8. function Dog(){
  9. this.bark = function () {
  10. console.log('dog bark');
  11. }
  12. }
  13. Dog.prototype = new Animal();
  14. //哈士奇
  15. var hashiqi = new Dog();
  16. //如果要真正写,就要写更贴近实战的原型链
  • 推荐 阮一峰老师?‍?的两篇文章:

Javascript 面向对象编程(一):封装

Javascript继承机制的设计思想