簡單了解javascript原型及原型鍊
原型和原型鍊式javascrpit中很重要的概念,但是無論書上還是網上 ,不少關于javascript原型和原型鍊的解釋都不易了解,是以本人在此介紹一下自己的簡單了解,希望對大家有幫助
原型
(閱讀時,請務必注意類型,比如執行個體對象是對象,構造函數是函數,原型對象是對象)
首先,先做一些定義
var Person = function(){ var name="person_private_name";}
var man = new Person();
Console.log(man.name); //undefined
在這裡提出一個問題,man是Person是一個執行個體對象,那麼man能不能獲得Person的屬性name呢?
答案是不能。
那要怎麼樣才能使得man獲得Person的屬性和方法?
答案是通過Person的原型對象。
那麼,這段代碼就應該改成
var Person = function(){ var name="person_private_name";}
Person.prototype.name="person_public_name";
var man = new Person();
Console.log(man.name); //person_public_name
這個Person.prototype到底是怎麼回事呢,我們通過圖來說明
注意!!prototype是一個指針,指向Person的Person.prototype對象,現在把Person.prototype放在Person内,純屬友善了解!!!!下圖綠色區域,是prototype指向的地方(Person.prototype)
我們把執行個體對象(man)需要通路的屬性和方法放在綠色區域裡面,這片綠色區域,就是Person的prototype(原型)。
當我們需要添加更多的可供執行個體對象(man)使用的屬性和方法的時候,我們就可以這麼做:
Person.prototype.age="person_public_age";
//向person原型添加屬性而不是向person添加
Person.prototype.eat=function(){alert("person eating!!");}
//向person原型添加方法而不是向person添加
需要補充的是,每個原型對象(prototype)都擁有一個constructor指向本身,比如Person有Person.prototype,那麼Person.prototype就有Person.prototype.constructor,而這個Person.prototype.constructor,就指向Person,用圖來說明
當然,上圖左右的兩種了解方式都可以,簡單來說就是Person的prototype指向Person.prototype(這不是廢話麼),然後Person.prototype.constructor指向Person(重點是這個)
現在,我們在看看書上的解析,應該好了解多了
我們建立的每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以由特定類型的所有執行個體共享的屬性和方法。 —– 《JavaScript進階程式設計》(第3版)147頁
原型鍊
說原型鍊,必須要給上面的部分補充 _ proto _ 這個概念。
當調用構造函數建立一個新執行個體後,該執行個體的内部将包含一個指針(内部屬性),指向構造函數的原型對象。ECMA-262第5版中管這個指針叫[[prototype]]。雖然在腳本中沒有标準的方式通路[[prototype]],但Firefox、Safari、Chrome在每個對象上都支援一個屬性_ proto _; ——《JavaScript進階程式設計》(第3版)148頁
簡單來說,就是執行個體對象(man)可以通過_ proto _找到構造函數(person)的原型對象(person.prototype)。
- 也就是找原型對象啦
- 也就是相當于找構造函數的那個共享區域啦 (注:這是我自己的了解)
”Firefox、Safari、Chrome在每個對象上都支援一個屬性_ proto “ 這也是很重要的一句話,文章開頭說務必注意類型,這裡就用上了。我們說執行個體對象是對象,那麼執行個體對象有 _proto _ 。但是原型對象呢?原型對象也是對象,是以原型對象也有_ proto _。是以本文第一張圖補充完整是這樣的
(注:網上有些解析Object的_proto_指向null)
就醬,一條很短的原型鍊就出來了,不難了解吧,有興趣的看看書裡的描述
假如我們讓原型對象等于另一個類型的執行個體,結果會怎樣呢?顯然,此時的原型對象将包含一個指向另一個原型的指針,相應地,另一個原型中也包含着一個指向另一個構造函數的指針。假如另一個原型又是另一個類型的執行個體,那麼上述關系依然成立,如此層層遞進,就構成了執行個體與原型的鍊條。這就是所謂原型鍊的基本概念。 —– 《JavaScript進階程式設計》(第3版)162頁
繼承
繼承是通過原型鍊來實作的,換個說法,繼承是通過延長這條原型鍊實作的。
從本文第三張圖做例子,我現在想在Person後面再加多個構造函數,命名為Person_Second,要怎麼做呢?
看第三張圖,圖中Person到Object是Person.prototype連到Object.prototype上面去的,那麼Person_Second.prototype也是要連到Person.prototype上面去的,在代碼中是這麼寫
var Person=function(){}
Person.prototype.person_name="person_name";
var Person_Second=function(){}
Person_Second.prototype = new Person(); //繼承了Person
Person_Second.prototype.person_second_name="person_second_name";
var women = new Person_Second();
console.log(women.person_name); //person_name
console.log(women.person_second_name); //person_second_name
看圖:
以上
如有錯誤請指出
歡迎加QQ交流:285482599