簡體   English   中英

javascript對象繼承-子類和超類

[英]javascript object inheritance - subclass and superclass

這兩種方法有什么區別?

第一種方法

// Shape - superclass
function Shape() {
    this.x = 0;
    this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
};

// Rectangle - subclass
function Rectangle() {
    Shape.call(this);
}

// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

第二種方法

// Shape - superclass
function Shape() {
    this.x = 0;
    this.y = 0;
}

// superclass method
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
};

// Rectangle - subclass
function Rectangle() {
    Shape.call(this);
}

// subclass extends superclass
Rectangle.prototype = new Shape();

var rect = new Rectangle();

我看到兩個區別:一個很大,一個很小。

小區別在於,在第二種方法中, Rectangle原型將不會正確設置其constructor屬性 它將指向Shape而不是Rectangle 這是JavaScript OO方法中的一個非常普遍的錯誤,大多數時候您都可以避免使用它,因為人們使用的不是很多的constructor屬性,但是它就在那里。

最大的不同是在第二個構造方法中對Shape()的附加調用 在您的特定示例中,事情或多或少都可以正常運行: Rectangle.prototype具有一些您可能不希望擁有的額外屬性( xy ,它們都等於零),但是這些屬性將被它們遮蓋。 Rectangle實例中的相應屬性。 同樣,這是一種非常常見但很小的錯誤,經常起作用,足以使您擺脫它。

第二種方法的問題在於,它僅在超類構造函數不需要任何參數時才起作用 您的示例恰好適合該描述,因為它所做的只是將某些屬性初始化為默認值。 但是在某些用例中,這種設置並不十分合適,並且在這種情況下不能使用第二種方法。

主要區別在於在第二種方法中, Shape構造函數僅被調用一次。 在第一種方法中,不調用Shape構造函數,而是Object.create(Shape.prototype)從原型創建一個新對象。 然后可以通過Shape.call每個子構造調用一次父構造函數。

與第二種方法一樣,您仍然可以為每個子類調用Shape.call ,但是它會在初始原型創建期間對構造函數進行額外的調用。

同樣,將第一種方法與Object.create會導致prototypeconstructor屬性被覆蓋,因此Rectangle.prototype.constructor = Rectangle; 用於重置constructor屬性。

第二種方法的主要缺點是,它需要對Shape構造函數進行一次額外的調用,才能創建一個對象用作Rectangle原型。 有不同的方法來避免它,例如,使用中間空函數:

function Rectangle() {
    Shape.call(this);
}

function f() {}
f.prototype = Shape.prototype;

Rectangle.prototype = new f();

如您所見,這顯然很笨拙。

因此,首選使用Object.create模式#1更為方便和有效。

但是請注意,兩個片段都有另一個問題:自己的屬性是用Shape.call(this);復制的Shape.call(this); 這也是不希望的。

Object.create不執行構造函數。

使用New調用等效於Object.create(object.prototype)+運行構造函數。

最大的實際區別是,當您使用new時,將調用超類的構造函數,而無需Shape.call(this);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM