javascript Prototype constructor的理解(一)

來源:互聯網
上載者:User

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:

(如發現理解錯誤指出,歡迎批評指正,相互學習)


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.