一篇文章讓你搞懂原型和原型鏈

2020-12-22 酷扯兒

本文轉載自【微信公眾號:手機電腦雙黑客,ID:heikestudio】,經微信公眾號授權轉載,如需轉載與原文作者聯繫

與多數面向對象的開發語言有所不同,雖然JavaScript沒有引入類似類的概念(ES6已經引入了class語法糖),但它仍然能夠大量的使用對象,那麼如何將所有對象聯繫起來就成了問題。於是就有了本文中我們要講到的原型和原型鏈的概念。

原型和原型鏈作為深入學習JavaScript最重要的概念之一,如果掌握它了後,弄清楚例如:JavaScript的繼承,new關鍵字的原來、封裝及優化等概念將變得不在話下,那麼下面我們開始關於原型和原型鏈的介紹。

什麼是原型?

JS中的對象包含了一個prototype的內部屬性,這個屬性所對應的就是該對象的原型。

我們先看下圖:a、b、c 分別為數組、對象、函數。

可以看到,三者都有一個屬性:__proto__

這個 __proto__ 稱作 隱式原型。

除此之外,c還有一個屬性:prototype

這個prototype 稱作 顯式原型。

小結一下:

所有引用類型(函數,數組,對象)都擁有__proto__屬性(隱式原型)所有函數除了有_proto_屬性之外還擁有prototype屬性(顯式原型)原型對象:每創建一個函數,該函數會自動帶有一個prototype屬性,該屬性是一個指針,指向了一個對象,我們稱之為原型對象。函數除了有_proto_屬性之外還擁有prototype屬性,我們藉助構造函數來尋找二者之間的關係。如下圖:

總結如下(結合上圖更容易理解):

1. 實例對象a只有__proto__(隱式原型),構造函數既有 __proto__(隱式原型)也有prototype(顯式原型)

2. __proto__ 和 prototype 都是一個對象,既然是對象,就表示他們也有一個 __proto__

3.實例對象a的隱式原型指向它構造函數的顯式原型,指向的意思是恆等於  

4. 當調用某種方法或查找某種屬性時,首先會在自身調用和查找,如果自身並沒有該屬性或方法,則會去它的__proto__屬性中調用查找,也就是它構造函數的prototype中調用查找。

什麼是原型鏈?

先看下圖,提出一個問題:

1. 在 Object的顯式原型添加屬性b,為什麼 示例對象p 能使用此屬性呢?p.b = b

2. 為什麼 p.a 為undefined

如下圖所示

1. 實例對象p的隱式原型(__proto__)是一個對象,有兩個屬性值:constructor 和 __proto__

2. p.__proto__.constructor 返回的結果為構造函數Person

3. p.__proto__.__proto__ .constructor 返回的結果為Object()函數

結合上面所講的顯式原型與隱式原型之間的關係,等同如下:

1. p.__proto__.__proto__ = Object.prototype

所以p.b列印結果為b,p沒有b屬性,會一直通過__proto__向上查找,最後當查找到Object.prototype時找到,最後列印出b,向上查找過程中,得到的是Object.prototype,而不是Function.prototype,找不到a屬性,所以結果為undefined,這就是 原型鏈,通過__proto__向上進行查找,最終到null結束。

總結:

1. 查找屬性,如果本身沒有,則會去__proto__中查找,也就是構造函數的顯式原型中查找,如果構造函數的顯式原型中也沒有該屬性,因為構造函數的顯式原型也是對象,也有__proto__,那麼會去它的顯式原型中查找,一直到null,如果沒有則返回undefined

2. p.__proto__.constructor == function Person(){}

3. p.___proto__.__proto__== Object.prototype

4. p.___proto__.__proto__.__proto__== Object.prototype.__proto__ == null

5. 通過__proto__形成原型鏈而非protrotype

01什麼是原型繼承?

Person.prototype 只是一個指針,指向的是原型對象,但是這個原型對象並不特別,它也只是一個普通對象。假設說,這時候,我們讓 Person.prototype 不再指向最初的原型對象,而是另一個類 (Animal)的實例,情況會怎樣呢?

執行該代碼 Person.prototype = new Animal() 後,Person的prototype指針指向發生了變化,指向了一個 Animal 實例。

當 p 去訪問 address 屬性時,js會先在 p 的實例屬性中查找,發現找不到後,就會去 Person 的原型對象上 查找。因為Person的原型對象已經被我們換成一個animal實例,所以就會先找animal實例的屬性,當發現還是沒有 address屬性,就會去Animal的原型對象上查找,最終找到。

這就說明,我們可以通過原型鏈的方式,實現 Person 繼承 Animal 的所有屬性和方法。

看到這,相信大家對原型和原型鏈的概念應該已經有了一定了解了,如果仍然不太理解,也不用氣餒,因為閉包及原型鏈是JavaScript最難理解的幾部分。相信之後在不斷的開發實踐中會使你理解的更為透徹,多學習多思考才能更快掌握。

相關焦點

  • 一篇文章讓你徹底了解 JS 原型鏈
    通過上面可以看到,"Animal.prototype"對象和 Animal 函數對象通過"constructor"和 "prototype"屬性實現了相互引用Step-->3: 查看對象 Object 的原型
  • 讓你秒懂JavaScript原型和原型鏈
    前端開發者原型和原型鏈是JavaScript中的難點也是重點,明白了原型和原型鏈會讓我們在後面不管是學習還是工作都會更加高效,並且原型和原型鏈會是面試中必不可少的話題。看完此篇文章一定會讓你對原型,原型鏈有深刻全面的了解。
  • 深入總結Javascript原型及原型鏈
    本篇文章給大家詳細分析了javascript原型及原型鏈的相關知識點以及用法分享,具有一定的參考價值,對此有需要的朋友可以參考學習下。如有不足之處,歡迎批評指正。我們創建的每個函數都有一個 prototype (原型)屬性,這個屬性是一個指針,指向一個原型對象,而這個原型對象中擁有的屬性和方法可以被所以實例共享一、理解原型對象無論什麼時候,只要創建了一個新函數,就會根據一組特定的規則為該函數創建一個prototype屬性,這個屬性指向函數的原型對象。
  • 一篇文章搞懂原子設計
    編輯導讀:原子設計是一種方法論,由原子、分子、組織、模板和頁面共同協作以創造出更有效的用戶界面系統的一種設計方法。本文作者圍繞原子設計,展開了五個維度的分析,希望對你有幫助。
  • 「文言句式」一篇文章帶你搞懂「定語後置」四種結構
    原文接上一篇的賓語前置,需要回顧的童鞋請點擊下面這篇文章:秋天第一篇文章,帶你搞懂倒裝中最「複雜」的賓語前置今天小編老師要通過一篇文章帶大家搞懂文言常見句式——「定語後置」。在講這種文言現象之前,要跟大家說一說什麼是「定語」和「中心語」。一、定語和中心語定語是一個語法名詞,在名詞前邊的表示領屬、性質、數量等等的修飾成分。名詞、代詞、形容詞、數量詞等都可以做定語 。在句子中,定語用於修飾主語和賓語。
  • 控制臺看懂原型
    原型的基本概念:每個實例對象都有一個私有屬性[[Prototype]](谷歌、火狐瀏覽器中實現為_proto__)指向創建他的構建函數的原型對象prototype。__proto__我們稱之為隱式原型,prototype為顯式原型。 接下來我們在控制臺中看看原型的指向。 在控制臺中我們創建一個對象,並且列印出來這個對象 可以看到我們創建的這個對象除了創建時設置的一個屬性a,還有個自帶的屬性__proto__。
  • 規範流程下的原型設計——你的原型真的有價值嗎?
    在前段時間翻譯的IDEO出品的《以人為本的設計指南》中,正好講到了構思到原型的階段,恰好我在進修的IDF設計思維課程也到了原型設計部分,因此準備出一篇原型相關的文章,分享所學同時也曝露一些目前國內設計行業存在的一些畸形現象。
  • 《騎馬與砍殺》的歷史原型:維吉亞王國和諾德王國的原型是什麼?
    騎馬與砍殺廣受歷史愛好者的歡迎作為一款很受歷史愛好者歡迎,而且有著較高歷史還原度的遊戲,騎馬與砍殺裡虛構的卡拉迪亞大陸上的六個政權,其實都是有中世紀歷史原型的,本文中提到的維基亞和諾德,原型分別是東歐的羅斯諸公國和北歐斯堪地那維亞的維京人,無論是遊戲還是歷史上,二者都有很深的淵源。
  • 毀童年~櫻桃小丸子人物原型大揭秘
    作者以自身為原型,描繪了小學三年級女生小丸子和父母、姐姐、祖父母以及同班同學們之間的喜劇故事。 《櫻桃小丸子》中的許多人物在現實生活中都有原型。比如,性格陰鬱的永澤君就確有其人。櫻桃子參加同學會的時候,搞錯了日期,晚到了一天,遇到了來取帽子的永澤君,於是寫了一篇小文章。濱崎同學也是有原型的,他本人還出了一本書叫《我是濱崎》。
  • 神兵小將:神兵獸原型慘遭曝光,神農獸原型太萌,天晶獸原型存疑
    神兵小將:神兵獸原型慘遭曝光,神農獸原型太萌,天晶獸原型存疑。神兵小將是一部深受漫迷喜歡的動漫作品,太多的90後和00後看過這部充滿玄幻的神話作品。神兵小將承載了我們童年的回憶,在動漫中諸多小將和元始天魔的手下作鬥爭。
  • AXURE原型設計:移動端搜索原型案例
    編輯導語:搜索框是每個軟體、系統、app必不可少的一個組成成分,本文作者今天就基於在實際工作中需要用到的原型,和大家分享一下移動端的搜索原型案例,以及設計出來的axure組件。
  • Protopie學習筆記:如何插入音頻文件,交互原型設計軟體入門教程
    上篇文章,和大家分享了Protopie如何在場景中插入視頻文件(文章連結見結尾),今天接著來看看如何在場景中插入音頻文件。Protopie的導入,支持3種音頻模式:mp3、wav、m4a。音頻的在導入場景以後,你會發現一個很其他的地方,當你把音樂導入至場景中後,在編輯頁面你可以看到音頻的存在,但是你在預覽的界面裡是看不到的。因為音頻是在視覺上無法體現的,哈哈哈,眼鏡看不見聲音,所以你可以把音頻的圖層拖動到最下方,只是你確保在演示時,音頻存在。
  • 海賊王神之谷與和之國-島嶼原型深度考察
    「你既然猜測神之谷在空島比魯卡下面,那神之谷會不會是火山島呀?」然後,幾百個壇友針對這個問題進行了長達3分鐘的激烈討論,沒想到居然考據出一些非常有趣的東西。在我文章《神之谷全解析》裡,我提出【神之谷位於空島比魯卡正下方】的猜想。根據240話提供的信息,火山噴發出的海樓石巖鹽結晶,與大氣中水氣結合,形成島雲和海雲。
  • 如何通過畫原型,寫文檔提高核心競爭力?
    不妨,先從畫原型這件事開始看看吧。一、原型圖是信息的表達原型圖是什麼?簡單的說,原型圖就是將想法落地轉化成其他人可以感知和理解的具體形式。這個其他人,可以是設計師、工程師、也可以是用戶。所以,原型圖很像是草稿,最後上線的那個產品就是草稿的終極版本。
  • Axure原型設計:移動端圖片輪播原型
    編輯導語:圖片輪播原型常應用於各大app的首頁,包括文章分享app、讀書app、商城app等等。通過這篇文章,本文作者希望和大家分享一下圖片輪播原型的作用、應用案例以及設計思路。下面我會和大家分享一些常用的圖片輪播案例:二、圖片輪播原型案例1. 頂端banner輪播圖元件這種是最常見最簡單的輪播圖了,一般會放在界面的頂端,或者有多個類別時,放在內容的最上面,將最精彩的內容,或者是廣告推送給客戶,一般應用於線上商城、外面平臺、文章閱讀平臺等等。
  • 海賊王人物原型大盤點,路飛原型是孫悟空,山治原名竟是鳴人?
    海賊王的人物同樣如此,其中的很多人物都不是心血來潮之作,而且都能在經典的文藝作品或者現實生活中找到原型。你可能對海賊人物如指諸掌,但他們背後原型和故事你真的都知道嗎?今天就讓我們一起去探秘,那些海賊王背後關於人物原型的有趣冷知識吧!
  • 豬八戒是以誰為原型創造的?《西遊記》中豬八戒原型綜述
    其中,關於本土說和外來說學者討論居多。眾說紛紜的豬八戒的原型符合學界百家爭鳴的學術氛圍。一、本土說豬八戒憨態可掬的形象深受廣大讀者的喜愛,在對豬八 戒的形象進行探源的過程中,持本土說的學者偏多。杭州佛教協會編的《靈隱》裡提道:「朱八戒傳說是三國時往西域求法的第一僧人朱士行。」
  • 賈寶玉原型是廢太子,林黛玉原型無人知曉,王熙鳳原型多數人猜對
    看「假語」找「真事」是《石頭記》作者對讀者的要求,只有知道書裡的人物原型才能有「真事」出現。本文就說說王熙鳳原型的故事。王熙鳳原型的故事的線索在兩個關鍵詞上,「末世」和「金陵」。王熙鳳正冊畫面是一片冰山,上面有一隻雌鳳。判詞曰:凡鳥偏從「末世」來,都知愛慕此生才。一從二令三人木,哭向「金陵」事更哀。
  • 黑馬程式設計師產品經理:你做的移動端原型被吐槽了嗎?
    我們接著前一篇的內容繼續,這篇的主題是關於移動端的原型規範。很多產品經理在企業中做移動端的原型時,被UI噴得體無完膚:「你這是原型嗎?」「你怎麼連基本的對齊都做不到?」「這兩個按鈕,倒是哪個是一級按鈕,哪個是次級的?」
  • 怪不得日漫裡的女孩很漂亮,原型都是女神,毛利蘭原型真的好美
    當然在動漫裡讓人驚豔的不僅僅只有場景,還有就是動漫裡的人物形象,尤其是日漫裡那些風格迥異但是卻都很漂亮的動漫女性角色,其實這些角色都不是漫畫家空穴來風創作的,都是有原型的,還都是女神級別的人物,相信你一定很好奇,接下來就讓絮叨帶你一探究竟。