2015-09-27 68 views
2
function Rectangle(length, width) { 
    this.length = length; 
    this.width = width; 
} 

Rectangle.prototype.getArea = function() { 
    return this.length * this.width; 
}; 

function Square(size) { 
    this.length = size; 
    this.width = size; 
} 

Square.prototype = new Rectangle(); 

這是我的代碼。Square是否正確地從Rectangle繼承?

Square是否正確地從Rectangle繼承?請建議我做出更改以正確執行此操作。

新的繼承和原型。

回答

3

Square是否正確地從Rectangle繼承?

不,但它很接近。下面是Square的變化:

function Square(size) { 
    Rectangle.call(this, size, size); 
} 

Square.prototype = Object.create(Rectangle.prototype); 
Square.prototype.constructor = Square; 

調用Rectangle創建Square的原型是一個可悲的是,常見的反模式;如果它實際上對我們在做這件事時沒有給出的論據做了什麼?

相反,您使用Object.create創建一個使用Rectangle.prototype作爲原型的對象。然後,您更新該原型的constructor屬性,以便指向正確的功能。然後,如果實際上有一個對象要初始化(例如,在Square函數中),則可以從Square調用Rectangle來初始化其位,然後再進行任何其他初始化操作。

在我切換到ES6轉換之前,我使用了一個名爲Lineage的助手腳本,因爲它有點冗長。該位創建原型可以被分離成一個功能,這也給了我們一個機會,迴避的事實合作,支持IE8它缺少Object.create

function derivePrototype(parent, child) { 
    var proto, ctor; 
    if (Object.create) { 
     proto = Object.create(parent.prototype); 
    } else { 
     ctor = function ctor() { };  // * See note 
     ctor.prototype = parent.prototype; 
     proto = new ctor; 
     ctor = null; 
    } 
    proto.constructor = child; 
    return proto; 
} 

然後

Square.prototype = derivePrototype(Rectangle, Square); 

* ctor = function ctor() { };創建兩個功能在IE8上(details),但它是無害的,因爲兩者都沒有被保留,並且該函數確實得到了一個名稱。


當然或者,您可以使用ES6,但是現在如果你想這樣做的網頁上,你不得不transpile它,因爲ES6是不是在野外尚未廣泛支持:

class Rectangle { 
    constructor(length, width) { 
     this.length = length; 
     this.width = width; 
    } 

    getArea() { 
     return this.length * this.width; 
    } 
} 

class Square extends Rectangle { 
    constructor(size) { 
     super(size, size); 
    } 
} 
+1

Thankyou。這些都是新的:) –

+1

@sᴜʀᴇsʜᴀᴛᴛᴀ:np(順便提一下,在發佈後的幾秒鐘內完成了更新)。你使用的模式顯示*很多*。 –