JS繼承之原型繼承
阿新 • • 發佈:2018-11-08
在繼承時,出於效率的考慮,我們會盡可能地將一些可重用的屬性和方法新增到原型中去,如果如此,我們就可以僅依靠原型就完成繼承關係的構建。
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;
}