7

我在閱讀上的JavaScript花園http://bonsaiden.github.com/JavaScript-Garden/約原型在JavaScript和例子之一是這樣的:爲什麼上市一類的實際構造在JavaScript重要

function Foo() { 
    this.value = 42; 
} 
Foo.prototype = { 
    method: function() {} 
}; 

function Bar() {} 

// Set Bar's prototype to a new instance of Foo 
Bar.prototype = new Foo(); 
Bar.prototype.foo = 'Hello World'; 

// Make sure to list Bar as the actual constructor <------------------- 
Bar.prototype.constructor = Bar; 

通知,上面寫着確保線路列表Bar作爲實際的構造函數。我真的迷失了這件事。我已經試過在沒有最後一行的情況下創建Bar()的新實例。但是在這些實例上調用「值」或「方法」會返回完全相同的結果。所以我想知道,指定構造函數有什麼需要(我認爲必須有)?

謝謝!!!

回答

6

每個函數都有一個prototype屬性,創建函數對象時,它的分配,它指向一個新創建的對象,從Object.prototype繼承,它有一個constructor屬性,簡單地回指向函數本身。

prototype屬性的目的是給出一種方法來實現繼承,使用構造函數。當您使用new運算符調用函數時,它將創建一個從該構造函數的prototype繼承的新對象。現在

,該constructor財產的目的是有辦法重新引用已創建的對象的構造函數,例如:

function Foo() {} 
// default value of the property: 
Foo.prototype.constructor == Foo; // true 

此屬性是由的Foo「實例」繼承,這樣你就可以知道哪個構造函數用於創建一個對象:如果您分配一個新的對象給函數的原型

var foo = new Foo(); 
foo.constructor == Foo; 

,這種關係將丟失:

function Bar() {} 
Bar.prototype = { inherited: 1 }; 

Bar.prototype.constructor == Bar; // false 
Bar.prototype.constructor == Object; // true 

而且這也影響了功能的實例:

var bar = new Bar(); 
bar.constructor == Bar; // false 
bar.constructor == Object; // true 

另一個類似的例子是,當你有使用構造繼承的兩個或兩個以上的水平,最常見的方式是用來表示繼承關係在功能之間,是指定第二級的屬性,例如:

function Parent() {} 

function Child() {} 
Child.prototype = new Parent(); 

上面的代碼有幾個問題,第一,它執行父構造函數來創建的繼承關係的邏輯,但那是另一個故事,在上面的例子中constructor財產也受到影響,因爲我們更換完全Child.prototype對象:

var child = new Child(); 
child.constructor == Parent; // true 

如果我們更換分配給它更換後的Child.prototypeconstructor屬性的值,它會顯示預期的行爲:

function Child() {} 
Child.prototype = new Parent(); 
Child.prototype.constructor = Child; 

var child = new Child(); 
child.constructor == Child; // true 
+0

感謝您的詳細解釋。這一切都有道理。唯一讓我感到困惑的東西,但我可以忽略的是它看起來有點兒在Child.prototype.constructor = Child –

+1

@Nik,不客氣!是的,這確實是循環設計,例如:'Object.prototype.constructor.prototype.constructor.prototype.constructor == Object;';-) – CMS

2

我相信這與用new關鍵字實例化Bar有關。我相信使用new將查找Bar.prototype.constructor。在該行之前,鏈接到Bar.prototype.contructor的對象是Foo類型,因此在沒有該行的情況下實例化時,它將創建Foo對象而不是Bar對象。

+0

謝謝基思! ;這是一個簡潔和重點解釋,以及 –

+1

不客氣!如果這有助於你可以+1嗎? –

相關問題