2013-05-27 84 views
3

方法1:這些原型聲明有什麼區別?

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

方法2:

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

各有什麼上述方法的區別和優點?

+2

與使用普通對象一樣,第二種樣式破壞'prototype'的所有現有內容。 – DCoder

+4

這與'x + = 10'和'x = 10'基本相同。 – georg

+0

另請參見[定義Javascript原型](http://stackoverflow.com/questions/17474390/defining-a-javascript-prototype) – Bergi

回答

4

在第一種情況下你是添加新屬性到現有的對象,在第二情況下,你是重寫Rectangle.prototype用一個新值(對象)。

改寫原型具有以下後果:

  • Rectangle.prototype.constructor不指向Rectangle了。當您使用對象字面量時,它將指向Object。這可以很容易地通過對原型分配

    Rectangle.prototype.constructor = Rectangle; 
    
  • 您可能鬆動的所有現有的屬性(除非你用constructor再次添加它們,等)來解決。

  • 現有的Rectangle的實例不會受到更改的影響。他們仍然會引用舊的原型,並且不會繼承新的方法/屬性。上現有實例

  • instanceof測試(即rect instanceof Rectangle)將失敗,由於instanceof比較原型和如在前面提到的點,現有實例保持其舊原型參考。

如果設置了原型創建任何實例之前,你沒有使用最後三個點擔心自己。

以上每種方法的區別和優點是什麼?

使用對象文字覆蓋原型的唯一優點是語法更簡潔。 IMO雖然沒有超過這個缺點。

您可以使用對象文字而不會通過合併兩個對象覆蓋原型:How can I merge properties of two JavaScript objects dynamically?

+0

感謝您的詳細解釋。得到它了! – user2424941

4

第二個打破了繼承鏈,並刪除了原來添加到原型之前的所有屬性。

讓我們看看我所說的「繼承鏈斷裂」這個例子的意思是:

function A(){} 
A.prototype.a = function(){} 
function B(){} 
B.prototype = new A(); 
B.prototype.b = function(){} 

B實例這裏繼承a方法。

但是,如果你

B.prototype = { b: function(){} } 

那麼這不再是這種情況。

+0

謝謝!現在更有意義 – user2424941

1

如果Rectangle.prototype{},這兩種方法之間沒有區別。