徹底理解javascript中的原型鏈

來源:互聯網
上載者:User

要弄清楚原型鏈就要先弄清楚 function 類型,在javascript中沒有類的概念,都是函數,所以它是一門函數式的程式設計語言。類有一個很重要的特性,就是它可以根據它的建構函式來建立以它為模板的對象。在javascript中,函數就有2個功能

第一、 作為一般函數調用
第二、 作為它原型對象的建構函式  也就new()

我們來看一個例子

function a(){this.name = 'a';}

當建立一個函數,它會發生什麼呢。

第一、它會建立1個函數對象 也就是a 本身

第二、它會建立1個原型對象@a(用@來表示)

第三、函數對象會有一個prototype指標,它指向了對應的原型對象,這裡就指向了@a

第四、@a對象中有一個construtor指標,指向它的建構函式,這裡就指向了a


這個prototype屬性究竟有什麼用呢。

其實prototype 屬性工作表示當前函數能夠控制的範圍(或者說它指明了當前函數是誰的建構函式),這裡a就是@a原型對象的建構函式,所以我們會看見有這種寫法

function a(){this.name = 'a';}var a1 = new a();

這就和其他常見語言相似了,new 就是調用原型對象(通過prototype指標)裡面建構函式(constructor)建立一個新的對象執行個體。

那麼修改了prototype指向對象裡面的屬性,也就影響了所有以它為模板建立的執行個體,我們可以這樣來驗證

function a(){this.name = 'a';}var a1 = new a();a.prototype.age = 1;alert(a1.age);

結果:1

那為什麼a1對象可以直接存取到age屬性呢。a1對象裡面我並沒有定義age屬性啊,

那是因為所有執行個體裡面都會有一個引用_proto_(在firfox,chrome下可以直接存取,ie不支援)指向了這個原型,這裡就是指向了@a,

function a(){this.name = 'a';}var a1 = new a();alert(a1._proto_ == a.prototype)
結果:true

在訪問屬性的時候,會先在a1對象內部中尋找,如果沒有,就會順著_proto_指向的對象裡面去尋找,這裡會到@a中尋找,找到就傳回值,沒有找到就返回undefined,用個成語來形容,就是順藤摸瓜嘛。

至此原型鏈的含義就出來了,由於原型對象也有一個_proto_指標,又指向了另一個原型,一個接一個,就形成了原型鏈。Object.prototype是最頂層的原型,所以如果修改了Object.prototype的屬性,那麼就影響了所有的對象。

在來看一段代碼

function a(){this.name = 'a';}function b(){this.age = 1;}b.prototype = new a();alert(new b().name);

我們顯示的將b的原型指向了a的一個執行個體,然後,b的執行個體也可以訪問a的屬性了。這就是javascript的繼承了,那為什麼b.prototype 指向的是a的一個執行個體,而不是直接指向a.prototype  呢。

b.prototype = new a.prototype;
如果像上面這麼寫,修改p.prototype中的屬性,那麼a的原型也會改變了,相當於是子類修改了父類,並且子類和父類的屬性糅合在了一起,這顯然是不合適的。換句話說,b也成為了@a的建構函式,a,b成了平級的關係。


我們可以下一個定義:

函數a 繼承函數b 也就是讓函數a成為函數b原型的一個執行個體的建構函式,建構函式裡面聲明的屬性是函數a自己的,原型執行個體裡面的屬性就是繼承b的

var $ = jQuery = function(selector,context){//不可能在自己的建構函式中又一次構造自己,所以返回了另外一個建構函式的執行個體return new init(selector,context);}         jQuery.fn = jQuery.prototype = {      size:function(){   return this.length;   }  }  function  init (selector,context){     } init.prototype = jQuery.fn;;}

這是jquery的一段源碼,我們在使用jquery的時候,並沒有使用new關鍵字,那它是如何構造對象的呢。

用上面的知識,可以解釋,jquery這裡只是一個一般函數的調用,它返回了jquery原型的另外一個建構函式建立的對象,也就是new init()

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.