1. 程式人生 > 其它 >js的六種繼承方式

js的六種繼承方式

原型鏈繼承

重點:讓新例項的原型等於父類的例項。
特點:1、例項可繼承的屬性有:例項的建構函式的屬性,父類建構函式屬性,父類原型的屬性。
缺點:1、新例項無法向父類建構函式傳參。
   2、繼承單一。
   3、所有新例項都會共享父類例項的屬性。

function Parent(name) {
  this.name = name || '阿巴'
  this.say = function () {
    console.log(this.name);
  }
}
Parent.prototype.job = function () {
  console.log('my job is teacher');
}
Parent.prototype.age = 24

function Child() {

}

Child.prototype = new Parent()
let child = new Child()
console.log(child.age);
console.log(child.name);

  

建構函式繼承

重點:用.call()和.apply()將父類建構函式引入子類函式
特點:1、只繼承了父類建構函式的屬性,沒有繼承父類原型的屬性。
   2、解決了原型鏈繼承缺點1、2、3。
   3、可以繼承多個建構函式屬性(call多個)。
   4、在子例項中可向父例項傳參。
缺點:1、只能繼承父類建構函式的屬性。
   2、無法實現建構函式的複用。每次用每次都要重新呼叫。
   3、每個新例項都有父類建構函式的副本,臃腫。

function Parent(name) {
  this.name = name || '阿巴'
  this.say = function () {
    console.log(this.name);
  }
}
Parent.prototype.job = function () {
  console.log('my job is teacher');
}
Parent.prototype.age = 24

function Child(name) {
  Parent.call(this,name)
}

let child = new Child('zzzz')
let child1 = new Child()
// child.name='阿布'
console.log(child.name);
child1.say()

  

組合繼承

重點:結合了兩種模式的優點,傳參和複用
特點:1、可以繼承父類原型上的屬性,可以傳參,可複用。
   2、每個新例項引入的建構函式屬性是私有的。缺點:呼叫了兩次父類建構函式(耗記憶體),子類的建構函式會代替原型上的那個父類建構函式。

function Parent(name){
  this.name=name
  this.age=12
}

function Child(name){
  Parent.call(this,name)
}

Child.prototype=new Parent()
let child=new Child('wl')
console.log(child.name);
console.log(child.age);

  

原型式繼承

重點:用一個函式包裝一個物件,然後返回這個函式的呼叫,這個函式就變成了個可以隨意增添屬性的例項或物件。object.create()就是這個原理。
特點:類似於複製一個物件,用函式來包裝。
缺點:1、所有例項都會繼承原型上的屬性。
   2、無法實現複用。(新例項屬性都是後面新增的)

function createObj(o){
  function F(){}
  F.prototype=o
  return new F()
}

let person={
  name:'llm',
  age:23,
  say:function(){
    console.log('AAAAA');
  }
}

let person1=createObj(person)
let person2=createObj(person)

console.log(person1.say());
person2.age=24
console.log(person2.age);
console.log(person1.age);

  

寄生式繼承

重點:用一個函式包裝一個物件,然後返回這個函式的呼叫,這個函式就變成了個可以隨意增添屬性的例項或物件。object.create()就是這個原理。
特點:類似於複製一個物件,用函式來包裝。
缺點:1、所有例項都會繼承原型上的屬性。
   2、無法實現複用。(新例項屬性都是後面新增的)

function createObj(o){
  function F(){}
  F.prototype=o
  return new F()
}

let person={
  name:'llm',
  age:23,
  say:function(){
    console.log('AAAAA');
  }
}

let person1=createObj(person)
let person2=createObj(person)

console.log(person1.say());
person2.age=24
console.log(person2.age);
console.log(person1.age);

  

寄生組合式繼承

重點:修復了組合繼承的問題

function Parent(name){
  this.name=name;
  this.colors=['red','blue','green']
  this.age=0
}

Parent.prototype.getName=function(){
  console.log(this.name);
}

function Child(name,age){
  Parent.call(this,name);
  this.age=age;
  this.name=name;
}

// 關鍵的三步
// let F=function(){}
// F.prototype=Parent.prototype
// Child.prototype=new F()

// 封裝一下
function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

function prototype(child, parent) {
  var prototype = object(parent.prototype);
  prototype.constructor = child;
  child.prototype = prototype;
}


// 當我們使用的時候:
prototype(Child, Parent);

let child1=new Child('lucky',18)
let child2=new Child('lucky')

console.log(child1,);
console.log(child2);