從個人校長生涯談原型和原型鏈

簡述引用類型

關於引用類型的賦值,上篇已經寫過。javascript

若是說引用類型是地點,咱們操做的就是它的地址;html

若是說引用類型是房子,咱們操做的就是它的鑰匙;java

若是說引用類型是人物,咱們操做的就是它的手機號;git

若是說咱們不用比喻,咱們操做的就是它的引用。github

至此,除了讚歎個人排比句是多麼蕩氣迴腸以外,你必定也發現:web

  • 引用類型就是一種有聯繫方式的數據類型
  • 這種間接關係,使不一樣變量共享同一數據成爲事實

例如函數

var a = {n: 1}

用變量a保存了{n: 1}的引用,經過這個引用能夠操做{n: 1},這個引用就是聯繫方式。學習

var b = a

a的引用賦值給b,變量b也保存了{n: 1}的引用,也能夠操做{n: 1},這就是共享。prototype

比如,你和你的房間的聯繫方式,就是房鑰匙。3d

由於你有房鑰匙,因此你纔可以進房間,操做房間裏面的東西。

若是路人甲默默複製一把,路人甲就能夠和你同樣,可以操做房間裏的東西,這就是共享。

問題來了————

你倆雖然有你房間的鑰匙,可是你倆擁有這個房間嗎?

答案是確定的。

即便是間接擁有,也是擁有。

好了,明白了上面的東西,原型就不是問題了。

個人校長生涯

在表達我對原型的理解以前,我想先講一個發生在我身上的不真實的故事。

接下來,我將講述個人一次創辦學校的經歷。

階段1、白手起家

回到多年前。

我是小強,此時我正打算建立一所學校,因此你們也能夠叫我小強校長。

首先,我要培養一個老師來替我上課,由於做爲一個校長,我還有不少其它事情要作。

很快,我將多年的教學經驗傳授給一個叫孔仔的人,培養出第一個老師。

後來呢,孔仔也培養出一批又一批的學生。

階段2、學科多樣化

學校算是建成,孔仔也能完成教學任務,不斷培養學生。

可是我發現一個問題,一我的的力量畢竟有限,雖然孔仔能完成基本教學,卻沒有精力在每一個學科上作到專精。

這就致使,培養出來的學生沒有專長,大多很普通。

終於有一天,個人學校獲得許多好心人的贊助,我當時表示力度大點十分感謝。

錢多了,我就能夠培養出更多的老師,不一樣特點的老師又能夠培養出不一樣特點的學生,這不正是個人畢生所追求的東西嗎?

因而,個人學校除了孔仔老師,又有了語文老師、數學老師、思想品德老師......

並且我還能夠培養更多學科的老師。

階段3、建設圖書室

不知什麼時候開始,有一些老師會找我申請一些教學方法的書,這我是十分支持的,能夠說是有求必應。

隨着申請的老師愈來愈多,我總結了一些不少老師會用到的教學方法的書,因而我就想:

不如我在本身辦公室旁邊建設一個圖書室,把這些經常使用的書放在裏面,老師們想看的時候來這裏看不就好了。

很快有老師向我反映,他們其實也有相同的困擾,學生也會向他們申請一些課程相關的書,並且常常是相同的。

因而我決定,只要是老師,都要有一個本身的圖書室,存放本身學生一般會用到的書或器材。

我也是老師,我是老師的老師。

因此,各科老師的圖書室通常都存放各自文化知識方面的教材,而個人辦公室存放的是教學經驗方面的教材。

立刻就要開工了!

但是我又發現,像《小學生必讀》這類書,幾乎在每一個老師的辦公室都有,我想:

不如把這類全校學生都讀的書,放在同一個地方吧,這樣就能夠省下更多錢吃喝玩樂建設學校。

我第一想到的,就是孔仔老師,孔仔老師畢竟是咱們學校的元老,同時他教的內容是最寬泛的、最不專門的,圖書室應該相對空曠,因此就把《小學生必讀》這類幾乎全部學生都會看的書籍統一放到他的圖書室吧。

因而我決定,在給每一個老師建造圖書室的同時,都建造一條隧道通往孔仔老師的圖書室。

個人圖書室也是那時候建的,因此個人圖書室也有一條通往孔仔老師的隧道。

這樣,我培養出來的老師,想看教學經驗方面的書籍,就能夠到個人圖書室。

而我校老師培養出來的學生,想看本身學習方面的書籍,就能夠到本身老師的圖書室;

若是沒有的話,就能夠經過本身老師的圖書室裏的隧道,來到孔仔老師的圖書室,看有沒有想看的書籍。

這樣個人學校就完美了,小強校長仍是挺不錯的哈?

原型和原型鏈

先把圖放在這裏。

javascript的培訓方式

在javascript中,Function扮演的就是校長的角色。

首先,他不想親自去培養學生,因此他培養出了第一個老師孔仔。

Object就至關於孔仔同樣能夠培養出學生,即經過new Object能夠建立對象。

可是,校長爲了學生的多樣化,又培養了語文老師、數學老師、思想品德老師等老師,並且還能夠按須要培養更多老師;

一樣,開發者想要建立多樣化的數據、符合須要的對象,諸如StringNumberBoolean這些函數對象也必不可少的,並且也能夠根據須要寫各類構造函數。

能夠看到,校長培訓出老師,老師再培訓出學生;

Function建立函數對象,函數對象再建立對象;

只不過javascript的培訓方式是new

javascript的圖書室

校長爲了不給每位老師買教學經驗方面的書,因此建立了本身的圖書室,用來讓本身培養的老師共享這些資源;

而咱們的Function,也並不想把那些經常使用的方法都複製一份,保存到ObjectStringArray...以及後來新建立的N多構造函數當中,因而新增一個屬性prototype(即原型對象),把一些公共的方法存在裏面;

Function讓它建立出來的函數對象共享prototype的方式,就是在經過new Function建立函數對象的同時,會使

被建立的函數對象.__proto__ = Function.prototype

好比,在建立Object的時候,會使

Object.__proto__ = Function.prototype

這個場景似曾相識?

沒錯,這就是我小強校長在建立本身的圖書室後,將圖書室鑰匙送給孔仔老師一把的情景。

此後,孔仔老師就能夠來個人圖書室,查閱教學經驗相關的書籍。

同理,Object也所以能夠訪問Functionprototype,使用Function爲他們精心準備的函數對象的方法。

驗證

Object.__proto__ === Function.prototype     // true

這裏的true表示的就是,鑰匙已拿到,Object已擁有Functionprototype

接下來,可能會更多用到「擁有」這個詞語

爲何呢?

雖然,根據開篇對引用類型的介紹,可知Object.__proto__ = Function.prototype所作的事情:

無非就是,Function把公共的方法都放在某個房間裏,再將鑰匙存在本身的屬性prototype裏;

在賦值時,就是複製了一把prototype裏的鑰匙,而後存在Object的屬性__proto__中。

從這個過程能夠看出,原型也不過是引用類型的賦值,就是經過一種聯繫方式間接擁有某個東西。

本篇文章開始說過,

即便是間接擁有,也是擁有。

首先,對引用類型的及其賦值的理解是必要的。

可是,在理解原型和原型鏈過程當中,能夠沒必要太關注引用類型賦值過程這種細節。

由於原型的目的,就是讓實例們都擁有有一個公共區域,方便使用一些經常使用的方法。

因此相似Object.__proto__ === Function.prototype這種嚇人的結構,它要表達的不過就是這個意思:

前者已經擁有了後者提供的公共區域。

就像個人校長生涯那樣,當我發現建圖書室的做用以後,並不止爲本身培養的老師建了圖書室。

只要是老師,都要有一個本身的圖書室,存放本身學生一般會用到的書或器材

這樣,把一些學生的教材也變成共享,就又省得給每一個學生都重複買教材。

也就是,不只Function建立函數對象時,會

被建立的函數對象.__proto__ = Function.prototype

並且函數對象在建立對象時,會

被建立的對象.__proto__ = 建立對象的函數對象.prototype

總結一下,只要new的時候,就會

實例.__proto__ = 建立者.prototype

即只要我建立了你,你就擁有了個人公共區域。

javascript的隧道

回顧個人校長生涯,在我即將開工給我和每位老師建圖書室以前,我又想到:

每一個老師的圖書室裏的書,也有不少是重複的,不如把這些重複的都放到元老級教師孔仔的圖書室吧。

但是學生只能進各自老師的圖書室,怎麼讓他們也能進孔仔老師的圖書室呢?

還記得睿智的小強校長是怎麼作的嗎:

在建每件圖書室的同時,修一條隧道能夠到達孔仔老師的圖書室,即Function建立對象的同時會

被建立的函數對象.prototype.__proto__ = Object.prototype

例如

Array.prototype.__proto__ === Object.prototype      // true

沒錯,對於javascript來講,Object就是孔仔老師,Objectprototype就是孔仔老師的圖書室。

爲了減小不一樣函數對象的prototype的重複,咱們把很通用的對象的方法都放到Objectprototype中,並經過上述方法讓其它函數都的prototype都擁有它。

這樣,每一個對象都擁有函數的prototype,每一個函數的prototype又都擁有Objectprototype,那麼每一個對象也都擁有Objectprototype,即對象總能找到早就給它們精心準備好的方法的;

不一樣原型之間這個不依不饒的關係,就是原型鏈。

對於學生來說,他們能夠去的辦公的總和、以及前後順序,就至關於咱們的原型鏈。

如圖

關於「隧道」的建成,還有一些重要問題:

實際上,被建立的函數對象.prototype.__proto__ = Object.prototype,並不是Function作到的,而是Object作到的。

這裏,Object實際上是使用的這一規則:

只要我建立了你,你就擁有了個人公共區域

由於javascript的建立方式是new,要想實現被建立的函數對象.prototype.__proto__ = Object.prototype,須要先有

被建立的函數對象.prototype = new Object()

即全部對象的prototype都是Object建立的,都是Object的實例。

其它函數對象的prototype所以才能擁有Objectprototype,即實現這種效果

被建立的函數對象.prototype.__proto__ = Object.prototype

那麼,若是你是類比個人校長生涯來理解原型的,你就會想:

new在故事中不是「培訓」的意思嗎,這是否是說,其它的圖書室都是孔仔「培訓」出來的?

其實,這裏咱們自圓其說靈活理解就好了,畢竟例子只是用來幫助理解的。

因此,咱們的「new」在這時候就是「建立」的意思。

在javascript中,全部對象的prototype都是Object建立的,那麼

在個人校長生涯中,故事可能就是這樣的:

個人校長生涯後記

這個時刻,學校還只是我(小強校長)和孔仔兩我的。

我說,孔仔,爲了實現資源的共享,我有一個想法。

孔仔說,啥想法?

我說,把你培養出來後,我已經很累了,可是咱們這個學校未來確定會獲得好心人的捐助,也必定會培養更多的老師,老師們也必定須要教學經驗方面的學習素材。若是每人我都發一套的話,就有點貴。因此我想給本身建造一個圖書室,專門放這些資料,這樣無論是你,仍是之後培養出來的老師,就均可以在這裏共享這些資源了。你以爲怎樣,孔仔?

孔仔說,小強校長真摳門英明啊!您看這樣如何,每一個老師也都建設一個本身的圖書室,這樣,不少給學生的教材就不用重複買了,他們想用想看的時候去老師的圖書室裏找就好了,更省錢。

我說,只給學生們開一個圖書室不能夠嗎,每一個老師都有圖書室會不會浪費?

孔仔說,不太好吧,畢竟不一樣學科的學生,使用教材的差別仍是挺大的,不是很通用,仍是建議每一個老師都有各自的圖書室,方便管理。

我說,有道理,可是總有一些通用的教材,好比《小學生必讀》這種,不必每一個老師的圖書室裏都放一套,不夠省錢。

孔仔說,您的意思是?

我說,放你那裏吧。

孔仔已經跟不上個人思路,問,其餘老師的學生都是去各自老師的圖書室啊,這樣只有個人學生能看到《小學生必讀》這類書吧?

我說,這還不簡單,每一個老師的圖書室都修一條隧道通向你的圖書室。

孔仔沉默。

我說,修圖書室的事情,就由你來負責吧!先給本校長來一個圖書室吧。

孔仔說,不能,我要先給本身修建一個圖書室,不然給你修建的時候不知道隧道通向哪裏。

我說,好吧。

今後,每當我培養出一個老師,孔仔就幫忙修建一個圖書室,同時挖一條隧道通往他本身的圖書室。

咱們的學校也愈來愈好。

其它你可能關心的事項

  • Function.prototype.__proto __ === Object.prototype ?

對。建設每一個圖書室的時候,孔仔都挖隧道通向本身的辦公室了,包括校長的辦公室。

  • Function.prototype.__proto === null ?

對。咱們說好把通用資源都放在孔仔辦公室,現在已經來到孔仔辦公室,還想去哪裏?

  • 先有的Function仍是先有的Object?

先有的Function。孔仔是我培養出來的,固然是先有的本校長。

  • 先有的Function.prototype仍是先有的Object.prototype?

先有的Object.prototype。否則孔仔修建圖書室的時候,怎麼知道把隧道通向哪裏。

  • constructor是什麼?

原型的constructor放的是該原型所屬的函數對象,即每一個圖書室裏都放在該圖書室所屬老師的聯繫方式,好比電話號碼。

  • 小強校長帥嗎?

顏值爆表。


若是你有其它關心的事項,能夠發表評論或者聯繫我,或者在這裏查看最新更改。

相關文章
相關標籤/搜索