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

ES5 继承

程序员文章站 2022-07-15 20:38:38
...
  1. 对象冒充继承
  2. 原型链继承
  3. 组合继承
  4. 原型式继承
  5. 寄生式组合继承
1.对象冒充继承

使用call或apply改变this指向,并执行了父类的构造函数

缺点: 无法继承父类原型(prototype)上的方法和属性

      function Father(s) {
        this.a = s;
      }

      Father.prototype.b = 3;
      Father.prototype.run = function () {
        console.log("run");
      };

      function Son(s) {
        Father.call(this, s);
      }
      let son = new Son("abc");

      console.log(son.a); //abc
      console.log(son.b); //undefined
      son.run();		  //TypeError: son.run is not a function
2.原型链继承

将父类的实例化对象赋值给子类的原型

缺点:覆盖了子类原有的方法和属性,所有子类共用一个父类的实例当原型

      function Father() {
        this.arr = [1, 2, 3];
      }
      Father.prototype.run = function () {
        console.log("run");
      };

      function Son() {}
      Son.prototype.jump = function () {
        console.log("jump");
      };
      Son.prototype = new Father();  //所有子类公用这一个父类的实例当原型

      let son1 = new Son();
      son1.arr.push(4);

      let son2 = new Son();
      son2.run(); //run
      console.log(son2.arr); //[1,2,3,4]
      son2.jump(); //TypeError: son2.jump is not a function
3.组合继承(对象冒充+原型链继承)

**缺点:**会调用两次构造函数(Son.prototype = new Father() 一次,new Son() 的时候在里面调用call的时候又一次),且会覆盖子类原有的属性和方法。

      function Father() {
        this.a = "a";
        this.arr = [1, 2, 3];
      }

      Father.prototype.b = 3;
      Father.prototype.run = function () {
        console.log("run");
      };

      function Son() {
        Father.call(this);
      }
      Son.prototype.jump = function () {
        console.log("jump");
      };
      Son.prototype = new Father();

      let son1 = new Son();
      son1.arr.push(4);

      let son2 = new Son();
      son2.run(); //run
      console.log(son2.arr); //[1,2,3]
      son2.jump(); //TypeError: son2.jump is not a function
4.原型式继承

解决了执行两次父类构造函数的问题,使用了一个中介Agent,一次父类构造函数都不会执行

缺点:只继承了父类原型上的属性和方法,父类内部的没有继承;所有子类共用同一个实例当原型;且会覆盖子类原有的属性和方法

      function Father() {
        console.log("qwer"); //全程没有log 'qwer'
        this.a = "a";
        this.arr = [1, 2, 3];
      }

      Father.prototype.b = 3;
      Father.prototype.run = function () {
        console.log("run");
      };
      function Agent() {}
      Agent.prototype = Father.prototype;

      function Son() {}
      Son.prototype.jump = function () {
        console.log("jump");
      };
      Son.prototype = new Agent();

      let son1 = new Son();
      console.log(son1.a);  //undefined
      son1.run();		//run
5.寄生式继承(完美继承)

封装inherit方法,传入父类和子类,利用Object.create()方法,让子类继承父类的原型

      function inherit(father, son) {
        let temp = son.prototype; //存一下son原有的prototype
        son.prototype = Object.create(father.prototype);

        if (Object.assign) {
          Object.assign(son.prototype, temp); //把原有的prototype再加进去
        }

        son.prototype.constructor = son;
      } 


	  function Father() {
        this.a = "a";
        this.arr = [1, 2, 3];
      }

      Father.prototype.run = function () {
        console.log("run");
      };

      function Son() {
        Father.call(this); //获取Father内部的方法和属性
        this.son = "i am son";
      }
      Son.prototype.jump = function () {
        console.log("jump");
      };
      inherit(Father, Son);

      let son1 = new Son();
      son1.arr.push(4);

      let son2 = new Son();
      console.log(son2.arr); //[1,2,3]
	  console.log(son1.son) // 'i am son'
      son1.run();	//'run'
      son1.jump();	//'jump'

上一篇: python 小白案例演练

下一篇: 继承