面向对象继承的几种方式

类式继承

一般类式继承是继承私有属性,调用父类通过call改变子类this指向

  function Person1(name,age){
   this.name = name;
   this.age = age;
  }
  function Coder1(name,age,job){
   //调用父类Person,通过call改变this
   Person1.call(this,name,age);
   this.job = job;
   console.log(this);
  }
  let p1 = new Person1('ccc',2021);
  let c1 = new Coder1('老八',56,'美食家')

 

拷贝继承

把一个对象的属性和方法直接复制到另一个对象中

使用for in 遍历父类身上的方法,只要是自身的就赋值给子类的原型

子类通过for in继承父类的方法(把父类的东西都继承过来),子类新加的方法父类不会有

  function Person2(name,age){
   this.name = name;
   this.age = age;
  }
  Person2.prototype.say = function(){
   console.log('我说'+this.name);
  }
  Person2.prototype.run = function(){
   console.log('我会跳');
  }
  function Coder2(name,age,job){
   Person2.call(this,name,age);
   this.job = job;
  }
  //Person2.prototype == Coder2.prototpe;//此时已经赋值了
  for(let attr in Person2.prototype){
   //如果父级有这些方法,就让父级复制一份给子类
   if(Person2.prototype.hasOwnProperty(attr)){
     Coder2.prototype[attr] == Person2.prototype[attr];
  }
  }
  //这样继承下来不是继承他的地址,改变一些方法也不影响Person
  Coder2.prototype.runing = function(){
   console.log('飞快的汽车');
  }
  let p2 = new Person2('Tom',20);
  let c2 = new Coder2('Jack',22,'reporter');
  c2.runing();
  console.log(Coder2.prototype);

使用Object.assign()拷贝

   function Person(name,age){
   this.name = name;
   this.age = age;
  }
  Person.prototype.say = function(){
   console.log('你的名字'+this.name);
  }
  Person.prototype.run = function(){
   console.log('我会跳');
  }
  function Coder(name,age,job){
     Person.call(this,name,age);
     this.job = job;
  }
  //Coder.prototype = Object.assign({},Person.prototype);//浅拷贝
  Object.assign(Coder.prototype,Person.prototype);
  Coder.prototype.say = function(){
   console.log('我是Rap');
  }
  let c = new Coder('paul',26,'会长');
  let p = new Person('rondo',26)
  c.run();
  p.say();

 

原型继承

原型继承主要是继承父类身上的属性和方法

1)创建一个空的构造函数

2)把空构造函数的原型等于父级的原型

3)把子类的原型等于new空函数

这样就达到了继承属性的目的

  function Pn(name){
   this.name = name;
}
 Pn.prototype.say = function(){
   console.log('交谈');
}
 Pn.prototype.run = function(){
   console.log('跳高');
}
 function Cn(name){
   Pc.call(this,name);
}
 function Temp(){}
 Temp.prototype = Pn.prototype;
 Cn.prototype = new Temp;

 

寄生组合式继承

子类私有继承父类私有,子类公有继承父类公有

属性继承:通过call继承的方法,将父类中的私有属性赋值一份到子类的私有属性中

方法继承:通过Object.create将父类的原型当作参数传入,返回值是一个空对象 将其赋值给子类的原型,这样子类的原型就通过proto原型链找到父类的原型

 function Pn(name){
   this.name = name;
}
 Pn.prototype.say = function(){
   console.log(this.name);
}
 function Cn(name){
   Pn.call(this,name);
}
 Cn.prototype = Object.create(Pn.prototype);

 

ES6继承

es6给我们提供了语法糖,可以用class创建类

通过extends继承父类属性,如果有添加constructor函数的话就必须使用super,否则会报错

super属于call继承,可以通过super给父类传参,super上面有死区,上方输入this也会报错

 class Person{
  constructor(name,age){
   this.name = name;
   this.age = age;
  }
  //静态方法
  static say(){
   console.log(1);
  }
  //动态方法
  say(){
   console.log(2);
  }
}
 class Coder extends Person{
   constructor(job,...arg){
     super(...arg);
     this.job = job;
  }
   coding(){
     console.log(this.job);
  }
}
 let p = new Person('Tom',22);
 let c = new Coder('Jack',18,'student');
 Person.say();//调用Person静态方法
 p.say();//调用Person动态方法
 c.say();//继承了父类的方法
 c.coding();//student 调用Coder动态方法
posted @ 2022-03-11 11:50  蜻蜓队zhang  阅读(183)  评论(0)    收藏  举报