1. 程式人生 > >JS繼承之原型繼承

JS繼承之原型繼承

在繼承時,出於效率的考慮,我們會盡可能地將一些可重用的屬性和方法新增到原型中去,如果如此,我們就可以僅依靠原型就完成繼承關係的構建。

function Shape() {} 
Shape.prototype.name = 'shape'; 
Shape.prototype.toString = function() {return this.name;};

function TwoDShape() {}
TwoDShape.prototype = Shape.prototype;
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.prototype.name = '2D shape'
; function Triangle(side,height) { this.side = side; this
.height = height; } Triangle.prototype = TwoDShape.prototype; Triangle.prototype.constructor = Triangle; Triangle.prototype.name = 'Triangle'
; Triangle.prototype.getArea = function() {return this.side*this.height/2;} var a = new Triangle(2,10); a.toString(); //"Triangle"

這樣寫,只繼承於原型,執行a.toString()時,JavaScript引擎會先檢視a物件中有沒有toString()方法,找不到就會去搜索該物件的原型屬性,此時該原型已經指向了TwoDShape的原型,而後者指向的又是Shape.prototype,且這裡採用的是引用傳遞,因此就能精簡查詢步驟。

但它存在著副作用,由於子物件與父物件指向的是同一個物件,所以一旦子物件對其原型進行修改,父物件也會隨著被改變,甚至所有的繼承關係也是如此。因此,我們可以通過利用一個臨時構造器來打破這種連鎖關係,即建立一個空函式f(),並將其原型設定為父級構造器。然後,我們既可以用new F()來建立一些不包含父物件屬性的物件,同時又可以從父物件prototype屬性中繼承一切。

function TwoDShape() {}
//----------臨時構造器----------
var F = function() {};
F.prototype = Shape.prototype;
TwoDShape.prototype = new F();
TwoDShape.prototype.constructor = TwoDShape;
TwoDShape.prototype.name = '2D shape'; 


function Triangle(side,height) {                                                                                                                                  
  this.side = side;                                                                                                                                      
  this.height = height;                                                                         
} 
//----------臨時構造器----------
var F = function() {};      
F.prototype = Shape.prototype;                                                                                             
Triangle.prototype = new F();   
Triangle.prototype.constructor = Triangle;
Triangle.prototype.name = 'Triangle'; 
Triangle.prototype.getArea = function() {return this.side*this.height/2;}    

基於此,我們可以將這些實現繼承關係的程式碼封裝起來

function extend(Child, Parent) {
  var F = function() {};
  F.prototype = Parent.prototype;
  Child.prototype = new F();
  Child.prototype.constructor = Child;
}