1. 程式人生 > 其它 >面向物件繼承的幾種方式

面向物件繼承的幾種方式

類式繼承

一般類式繼承是繼承私有屬性,呼叫父類通過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動態方法