雖然看過這篇博文JavaScript prototype以後對原型理解再也不那麼模糊了,可是依然還有不少理解不甚透徹的地方。好比,今天看到一個原型式繼承的例子,又有些困惑,因而找了些帖子看看,有了一些本身的理解,貼在這裏,但願理解不對的地方你們能夠幫我指出來,多謝了!javascript
先看一段代碼:html
function Person(){ console.log("in 'Person'"); } function Woman(){ console.log("in 'Woman'"); } var woman=new Woman();//in 'Woman' woman.constructor;//function Woman(){console.log("in 'woman'");} var person=new Person();//in 'Person' person.constructor;//function Person(){console.log("in 'person'");}
以上定義了兩個function,各自實例化出一個對象後,在console中查看它們的constructor,一切正常。目前兩個function之間尚未任何關係,下面用prototype讓它們之間掛鉤。設置Woman類的prototype是Person類,這個時候再來查看constructor的狀況。java
function Person(){ console.log("in 'Person'"); } function Woman(){ console.log("in 'Woman'"); } Woman.prototype=new Person(); var woman=new Woman();//in 'Woman' /**constructor指向的是Person函數**/ woman.constructor;//function Person(){console.log("in 'person'");} var person=new Person();//in 'Person' person.constructor;//function Person(){console.log("in 'person'");}
能夠看到woman的constructor指向了Person函數,這是爲何呢?ide
咱們知道,每一個函數都有默認的prototype,這個prototype.constructor默認指向的就是這個函數自己。在未給Woman指定Person做爲原型以前,Woman.prototype.constructor或者woman._proto_
.constructor指向的就是Woman函數。可是當這樣作以後:函數
Woman.prototype=new Person();
Woman函數的prototype被覆蓋成了一個Person對象。
咱們知道,constructor始終指向的是建立自己的構造函數,所以Woman.prototype.constructor天然就指向了建立Woman.prototype這個Person對象的函數,也就是Person函數。這樣一來,woman對象的constructor指向就不對了,所以在網上大多關於原型繼承的帖子裏都會建議咱們作這樣的修改:prototype
Woman.prototype.constructor=Woman; var woman=new Woman();//in 'Woman' woman.constructor;//function Woman(){console.log("in 'woman'");}
這樣修正之後,constructor的指向就正確了。
可是,爲何要這樣修正呢?不修正會有什麼後果呢?code
這是我最困惑的地方,由於我試驗後發現,就算不作這樣的修正,new Woman()的時候也不會有什麼問題,雖然我還不理解JS是如何作到的,可是它確實找到了正確的構造函數去作實例化。最後我在stackoverflow上找到了一個回答What it the significance of the Javascript constructor property?,裏面提到:htm
The constructor property makes absolutely no practical difference to anything internally. It's only any use if your code explicitly uses it. For example, you may decide you need each of your objects to have a reference to the actual constructor function that created it; if so, you'll need to set the constructor property explicitly when you set up inheritance by assigning an object to a constructor function's prototype property, as in your example.對象
因此,即便不作這樣的修正也不會有什麼影響,它主要防止一種狀況下出錯,就是你顯式地去使用構造函數。好比,我並不知道woman是由哪一個函數實例化出來的,可是我想clone一個,這時就能夠這樣:blog
var woman = new Woman(); ... ... ... var woman1 = woman.constructor();