Prototype屬性
a) Prototype:每一個函數都包含一個prototype屬性,這個屬性指向的是一個對象的引用;而對已每一個函數(類)的執行個體都會從prototype屬性指向的對象上繼承屬性,換句話說通過同一個函數建立的所有對象都繼承一個相同的對象。
b) 通過new 關鍵字和建構函式建立的對象的原型,就是建構函式的prototype指向的那個對象
下面通過一個函數可以解釋a b兩條說明的問題,代碼如下
function A(name){ this.name = name;}var a1 = new A("aa1");var a2 = new A("aa2");
用chrome的take heap snapshot可以看到下面的東西
<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHAgYWxpZ249"left"> 圖1.2
分析說明:1.2,可以發現a1、a2對象的_proto_右邊的@後面的值都是1426796,等於Prototype對象歲代表的@1423679,所以有如下關a1.__proto__ ==== a2.__proto__=== A.prototype
用映像直觀表示如下:
圖 1.3
到此說明了a,b兩點是正確的。
同事上面的也可以論證一下觀點(該觀點摘自javascript權威指南):
1) 同一個類的所有執行個體都從同一個原型對象上繼承屬性
2) 若且唯若兩個對象繼承自同一個原型對象時,他們才是屬於同一個類的執行個體
特別說明:只有建構函式才有prototype屬性,而建構函式的執行個體是沒有該屬性的,也就是說console.log(a1.prototype)輸出的是undefined。在javascript中,每個函數都自動有一個prototype屬性,而不是每一個對象擁有prototype屬性
原型屬性與執行個體對象的建立與否沒有關係,它在對象建立之前就已經存在
Constructor屬性
觀察藍色背景部分,每一個函數的Prototype屬性指向的對象都包含唯一一個不可枚舉屬性constructor,該屬性的值是這麼一個對象:它指向了它所在的建構函式。
Prototype中的constructor指向的是functionA()這個它所在的建構函式
圖 1.4
直觀表示如:
圖 1.5
此時 alert(A.prototype.constructor)的結果是:
function A(name){ this.name = name;}通過上面的兩個圖,可以得到如下的結論:在Prototype屬性指向的對象中存在預先定義好的constructor屬性,每個建構函式的執行個體繼承了這一屬性,所以在不重寫Prototype對象的情況下,執行個體的constructor指向它們的建構函式
Var a = new A();
a.constructor === A// =>true
如果重寫了Prototype對象,代碼如下:
A.prototype = { getName:function(){return this.name} };
此時產生的A的對象只有兩個即:a1,a2,而沒有Prototype對象,如下
問題出來了,那這個Prototype對象到哪兒去了呢?看綠色方框裡面的@81203,通過它進行尋找,在Object執行個體中找到了這個對象的資訊
注意:新定義Prototype對象的話,該Prototype對象原有的constructor屬性會丟失,該Prototype此時所指的對象(即{getName:function(){return this.name}}對象)的constructor就是Object,事實上{getName:function()}就是一個Object對象。相信如果A.prototype={getName:function(){returnthis.name}}換成這樣寫的話,理解起來會方便寫:
Var obj = {getName:function(){}}
A.prototype = obj;
//或者這樣寫:
Var obj = new Object();
Obj.getName = function(){
};
A. prototype = obj;
此時用圖形表示a1,a2,prototype對象的關係如下:
通過這個圖可以很直觀的看出:
a1.constructor === A//=>false
a1.constructor === Object//=>true
A.prototype.constructor === Object
.修改這個問題的辦法就行給重定義的Prototype對象顯式的添加一個constructor屬性,修改其constructor的指向:
A.prototype = { constructor:A, getName:function(){return this.name} }
那麼通過chrome的Take Heap Snapshot分析得到1.3:
(如發現理解錯誤指出,歡迎批評指正,相互學習)