2014-05-15 221 views
0

這個問題純屬學術價值。爲什麼對象的構造函數返回Object()而不是構造函數?

給定一個構造函數Foo()

function Foo(){ 
    this.x = 1; 
} 

和類的一個實例:

var o = new Foo(); // Instance of Foo() 

console.log(o.constructor); // => Foo(): The constructor of `o` is `Foo()` - this makes sense so far. 

但是,如果設置了手動Foo()構造函數的prototype屬性...

Foo.prototype = { z: 3}; 

var o = new Foo(); // Instance of Foo() 

o's constructo R爲Object(),所以不Foo()

console.log(o.constructor); // => Object {} 

我得到Foo()(鄰的構造函數的prototype屬性)發生變化,但不是Foo()仍然Foo()實例的構造函數?是不是prototype屬性 Foo()被改變,而不是Foo()本身?

+1

你問的'.constructor'屬性不是一個魔術屬性。這是一個默認分配給每個函數的原型對象並指向該函數的普通屬性。當你替換函數的默認原型對象時,你會擺脫那個默認的'.constructor'屬性。 –

+0

因此,爲了理解,'o'從'Foo.prototype.constructor'繼承它的構造函數屬性?因此,通過用'{}'等對象覆蓋'Foo.prototype',而不是繼承該對象的構造函數屬性,因此返回'Object()'作爲構造函數而不是'Foo()'。那是對的嗎? – dkugappi

+0

我想我的遺漏鏈接是'o.constructor'從'Foo.prototype.constructor'繼承的事實。我出於某種原因認爲'o.constructor'是任何JS對象的一個​​屬性,而不是從其構造函數的'prototype'屬性繼承的屬性。 – dkugappi

回答

2

構造函數不過是一個簡單的函數。任何函數都是構造函數。

真正的和唯一的魔法在new operator:它是創建給定「類」的新實例的那個運算符。

引述MDN:

當執行代碼的新富(...),下面的事情發生:

  • 一個新的對象被創建,從foo.prototype繼承。

  • 構造函數foo被調用時指定的參數和 綁定到新創建的對象。新foo相當於新的 foo(),即如果未指定參數列表,則會調用foo而不使用 參數。

  • 構造函數返回的對象成爲整個新表達式的 結果。如果構造函數 未明確返回對象,則在步驟1中創建的對象替代地使用 。 (通常構造函數不返回值,但他們 可以選擇這樣做,如果他們想覆蓋普通對象 創建過程。)

注意順序:你不適用newFoo(),但是到Foo。這就是爲什麼你也可以寫

var o = new Foo; 
相關問題