ES5继承

151 阅读2分钟

1.冒充继承

  • 使用构造函数的技术或者对象冒充的技术,解决引用共享和父类无法传参的问题。
  • 没有原型。
function Box(age){
     this.name=['zhang','wang','li'];  
     this.age=age;
}
function Desk(age){
    Box.call(this,age);//对象冒充,给超类型传参
}
var desk=new Desk(200);  

2.组合继承

  • 使用原型链+借用构造函数的模式解决没有原型的问题。
  • 出现父类被调用两次并且,子类原型上的属性值为undefined
function Box(age){
    this.name=['zhang','wang','li'];   
    this.age=age;
}
Box.prototype.run=function(){    return this.name+this.age;   }
function Desk(age){  
	Box.call(this,age);//对象冒充
}
Desk.prototype=new Box();//原型链继承    
var desk=new Desk(100);  

3.原型式继承

  • 解决不通过new 父类的方式赋给子类的原型,将父类的原型赋值给一个新的函数的原型,即new新的函数=new父类。
  • 这种继承借助原型并基于已有的对象创建新对象。
  • 缺点,每次都要创建新函数。
function Ball(_a){
    Box.call(this,_a)
}
function F() {};
F.prototype = Box.prototype;
Ball.prototype = new F();
Ball.prototype.constructor = Ball;

let b = new Ball(10)

4.寄生式继承

  • 将原型式+工厂模式结合而来,目的是为了封装创建对象的过程。
 function extend(subClass, supClass) {
      // 创建一个中间替代类,防止多次执行父类(超类)的构造函数
      function F() { }
      // 将父类的原型赋值给这个中间替代类
      F.prototype = supClass.prototype;
      // 将原子类的原型保存
      var proto = subClass.prototype;
      // 将子类的原型设置为中间替代类的实例对象
      subClass.prototype = new F();
      // 将原子类的原型复制到子类原型上,合并超类原型和子类原型的属性方法
      // Object.assign(subClass.prototype,proto);
      var names = Object.getOwnPropertyNames(proto);
      for (var i = 0; i < names.length; i++) {
          var desc = Object.getOwnPropertyDescriptor(proto, names[i]);
          Object.defineProperty(subClass.prototype, names[i], desc);
      }
      // 设置子类的构造函数时自身的构造函数,以防止因为设置原型而覆盖构造函数
      subClass.prototype.constructor = subClass;
      // 给子类的原型中添加一个属性,可以快捷的调用到父类的原型方法
      subClass.prototype.superClass = supClass.prototype;
      // 如果父类的原型构造函数指向的不是父类构造函数,重新指向
      if (supClass.prototype.constructor !== supClass) {
          supClass.prototype.constructor = supClass;
      }
  }

  function Ball(_a) {
      this.superClass.constructor.call(this, _a);
  }
  Ball.prototype.play = function () {
      this.superClass.play.call(this);//执行超类的play方法
      console.log("end");
  }
  Object.defineProperty(Ball.prototype, "d", {
      value: 20
  })

  extend(Ball, Box);

  var b = new Ball(10);
  console.log(b);