標籤:
相信很多對javascript原型初步瞭解的人都知道prototype,constructor,__proto__這些名詞,也在一定程度上可以使用這些對象、屬性。甚至知道在建構函式的原型上定義方法供執行個體對象使用。但是很多人對原型的整個構成以及prototype和constructor等的關係沒有明確的知識架構,現在就隨我看一下他們之間的關係到底是什麼樣的吧~(本文預設讀者已經對原型有一定瞭解,如果還沒有開始瞭解原型建議閱讀《javascript進階程式設計》一書關於原型的章節)
好的,現在我們就以一段代碼為基礎對原型進行分析
1 function Foo() {};2 var foo = new Foo();
3 console.log(Foo.prototype);4 console.log(foo.__proto__);5 console.log("Foo.prototype.constructor----" + Foo.prototype.constructor);6 console.log("foo.__proto__.constructor----" + foo.__proto__.constructor);7 console.log("foo.constructor----" + foo.constructor);
首先貼出這段代碼的答案在進行分析
可以看出 Foo.prototype 和 foo.__proto__ 為相同的值,並且值為一個對象,其實 __proto__ 是為了方便尋找一個執行個體化對象的建構函式的原型而專門設定出的屬性,所以他的值必然與他建構函式的prototype相同。那prototype是怎麼產生的呢?來看圖
當Foo函數作為建構函式執行個體化foo對象時,會建立出一個新對象並將它關聯在Foo.prototype上(答案1),並且為foo建立與Foo.prototype的串連(foo.__proto__(答案2))。foo獨立儲存Foo內部的屬性及方法並單獨執行操作,如果在foo內部尋找不到需要的屬性(方法只是屬性類型為函數是的一個別名)則向上尋找,如果存在於Foo.prototype中,怎只用或修改建構函式原型上的屬性。
Foo.prototype是一個對象,有上面代碼的答案就可看出,這個對象存在一個不可枚舉的屬性 constructor ,指向建立出它的建構函式,所以Foo.prototype.constructor 是Foo這個函數(答案3)。因為foo.__proto__與Foo.prototype相等,所以foo.__proto__.constructor是Foo這個函數(答案4)。又因為foo可以通過原型鏈尋找並使用Foo.prototype的屬性,所以~~foo可以使用constructor屬性,而constructor屬性的指向前面已經說過,所以foo.constouctor也是Foo這個函數(答案5)。
梳理javascript原型整體思路