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);
}
}
Thankyou。這些都是新的:) –
@sᴜʀᴇsʜᴀᴛᴛᴀ:np(順便提一下,在發佈後的幾秒鐘內完成了更新)。你使用的模式顯示*很多*。 –