javascript類式繼承設計模式簡單介紹

antzone發表於2017-04-04

一般說來,我們在設計類的時候,實際上就是希望能減少重複性的程式碼,使用繼承可以完美的做到這一點,藉助繼承機制,你可以在現有類的基礎上再次進行設計並且充分利用它們已經具備的各種方法,而對設計的修改也更為輕鬆。舉例說明:

[JavaScript] 純文字檢視 複製程式碼
function Person(name){
  this.name = name;
}
Person.prototype.getname = function(){
  return this.name;
}
  
function Bloger(name,blog){
  Person.call(this,name);
  this.blog = blog;
}
var bloger = new Bloger("antzone","http://www.softwhy.com");
console.log(bloger.name=="antzone");
console.log(bloger.blog)
console.log(bloger.getname()=="antzone");

通過上例可以看到,Bloger在其內部通過call動態呼叫了其父類Person的原生屬性和方法,即可以理解為Bloger繼承了Person,成為它的一個子類,但是細心的同學會發現,Person原型物件中的方法,僅僅依靠call,是不能繼承過來的,這也就是會提示"bloger.getname is not a function"的原因所在了。不過不用擔心,對上述程式碼稍作處理,即可解決這個問題:

[JavaScript] 純文字檢視 複製程式碼
function Person(name){
  this.name = name;
}
Person.prototype.getname = function(){
  return this.name;
}
  
function Bloger(name,blog){
  Person.call(this,name);
  this.blog = blog;
}
/*請注意以下兩行程式碼*/
Bloger.prototype = new Person();  
Bloger.prototype.constructor = Bloger;
  
var bloger = new Bloger("antzone","http://www.softwhy.com");
console.log(bloger.name=="antzone");
console.log(bloger.blog)
console.log(bloger.getname()=="antzone");

在這裡需要對這兩行程式碼解釋一下,我們知道,每一個建構函式都有一個prototype屬性,這個屬性指向該建構函式的原型物件,其實原型物件也是例項物件,只不過在原型物件中定義的屬性和方法可以提供給所有的例項物件共享,由此可以得出,新新增兩行程式碼的意圖就是設定子類的原型物件指向父類的一個例項化物件,而父類的例項化物件會把父類的原型屬性方法統統繼承過來,這樣也就達到了我們的目的,子類的原型繼承了所有父類例項物件具有的屬性和方法。

但是還應該注意Bloger.prototype.constructor = Bloger;這行程式碼,因為把子類的prototype設定為父類的例項時,其constructor屬性會指向父類,所以要設定子類原型的constructor重新指向子類,至此,已經完美實現了javascript的類式繼承。

為了簡化子類的宣告,可以把擴充套件子類的整個過程寫名為extend的函式中,作用就是基於一個給定的類結構去建立一個新的類:

[JavaScript] 純文字檢視 複製程式碼
function extend(childClass,parentClass){
  var F = new Function();
  F.prototype = parentClass.prototype;
  childClass.prototype = new F();
  childClass.prototype.constructor = childClass;
}

有了這個extend這個函式,就可以很方便的擴充套件子類了,只需呼叫這個函式即可,上述新增的兩行程式碼可改為extend(Bloger,Person), 一樣可以實現完全繼承。

相關文章