2016-09-14 95 views
0

我可能已經閱讀了15種不同的書籍,文章,或者與JavaScript Prototypal Inheritance有關的SO問題,每種都有稍微不同的處理方式,所以我想一勞永逸地解決這個問題:原型繼承設置

function Rectangle(h, w){ 
    this.height = h; 
    this.width = w; 
    console.log("Rectangle ctor: "+ this.height + "x" + this.width); 
} 

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

var a = new Rectangle(3, 4); 

console.log(a.getArea()); 

function Square(l){ 
    this.height = l; 
    this.width = l; 
    console.log("Square ctor"); 
} 

Square.prototype = new Rectangle(); 
Square.prototype.constructor = Square; 

var b = new Square(5); 

console.log(b.getArea()); 

此示例按預期工作。 Square對象繼承自Rectangle,因此它可以使用getArea()方法。然而,有一件事我總是看到,根據我看起來的不同而做得不同。

而不是做Square.prototype = new Rectangle(),我看到人們使用Square.prototype = Object.create(Rectangle.prototype)。當我測試了這一點,都出現在同樣的方式運作,我注意到的唯一區別是,當我這樣做:

console.log(new Rectangle()); 
console.log(Object.create(Rectangle.prototype)); 

這記錄了new Rectangle()包括heightwidth屬性,然後將記錄Object.create(Rectangle.prototype)除了heightwidth之外,它記錄了相同的東西。

所以我的問題是,爲什麼有些人用一個而不是另一個做?比另一個更有利嗎?我理解它的方式,使用new Rectangle()的那個將獲得其原型上的高度和寬度屬性,這可能會導致問題,更正嗎?

有人可以請說一說嗎?謝謝!

編輯

我也意識到,使用new Rectangle()作爲廣場的雛形時,它實際上調用的構造方法(可以做一些在某些情況下是有用的),而Object.create()方法沒有。是否與用例有關的兩種不同用法背後的推理是否應該調用構造函數來生成子類型中可能需要的某種對象狀態?

+0

一勞永逸?使用ES6'類'語法。 – Bergi

+0

是的,但並非所有的瀏覽器都可以使用ES6,目前我還沒有使用Babel。再加上它更多地瞭解我感興趣的內幕。 –

回答

1

我想你自己回答了你的問題。 new Rectangle()Object.create(Rectangle.prototype)之間的區別在於前者調用構造函數,後者不調用構造函數。因此,您應該始終使用Object.create()。否則,構造函數將被調用兩次(如您在示例中所見)。

另外,在ECMAScript 6中,您可以使用class syntax,它可以簡化許多事情,如繼承。

+0

好的,謝謝,我想我更傾向於確定一個版本在技術上是否被「棄用」,或者它們是否完全有效取決於您的使用情況。在玩弄兩者後,看起來'Object.create(Rectangle.prototype)'是一種更乾淨的做事方式,因爲你1)不必再花費額外的時間調用構造函數,2)你沒有原型屬性被子類型對象遮蔽(當使用'new'時,高度和寬度被添加到'Square.prototype'中,然後被Square的構造函數中的this.height和this.width所影響) –

+0

@MattHintzke IMO only' Object.create()'選項是有效的。 –

+1

@MattHintzke它更乾淨,更不容易出錯。用於創建原型的「新」實際上已被棄用,即使在邊緣情況下其工作原理相同。 – Bergi