如何理解JavaScript的原型和原型鏈?

以前有朋友在公衆號給我留言,問問怎麼去理解原型和原型鏈的問題。這個問題,在面試中,不少同窗常常都會遇到。
回覆多了,以爲你們對這塊知識點理解仍是不夠深。因而決定今天來給你們講講,方便你們記憶。

c215166588b191ec66cfdcfcfdb31ab35f7.jpg

JavaScript的特色

JavaScript是一門直譯式腳本語言,是一種動態類型、基於原型的語言。 JavaScript的靈活性不亞於C++,你可使用JavaScript嘗試不一樣的程序設計範型。
好比類jQuery風格的函數式編程、基於過程的指令式編程、以及基於原型的面向對象編程。
不一樣於Java、C#等面嚮對象語言,JavaScript採用基於原型的繼承方式。

爲啥會有原型和原型鏈?

1994年,網景公司(Netscape)發佈了Navigator瀏覽器0.9版,可是剛開始的Js沒有繼承機制,更別提像同時期興盛的C++和Java這樣擁有面向對象的概念。在實際的開發過程當中,工程師們發現沒有繼承機制很難解決一些問題,必須有一種機制能將全部的對象關聯起來。
Brendan Eich鑑於以上狀況,但不想把Js設計得過爲複雜,因而引入了new關鍵詞 和 constructor構造函數來簡化對象的設計,引入了prototype函數對象來包含全部實例對象的構造函數的屬性和方法,引入了proto和原型鏈的概念解決繼承的問題。

原型模式

  • 每一個函數都有一個prototype(原型)屬性
  • 這個屬性都有一個指針,指向一個對象
  • 這個對象包含由特定類型全部實例共享的屬性和方法
  • 使用原型的好處是 可讓全部對象實例共享它包含的方法和屬性
經過in操做符和hasOwnProperty來判斷給定屬性是來自於原型仍是實例
in- true 表明屬性在對象中存在 來自實例或者來自原型
hasOwnProperty- true表明屬性來自於實例 是實例屬性

原型鏈

ECMAScript中只支持實現繼承,並且是經過原型鏈的方式來實現的。因此原型鏈是JavaScript實現繼承的一種重要方式。

用戶定義類型的原型鏈
咱們通常如何來檢查JavaScript的變量數據類型?通常咱們都是經過instanceof關鍵字,能夠基於原型鏈來檢測變量的類型。
咱們能夠先構造一個原型鏈,再用instanceof來檢測類型:

由上面講的instanceof的結果,能夠判斷這些類型的繼承層級:
事實上instanceof是經過原型鏈來檢測類型的,例如L instanceof R: 若是R.prototype出如今了L的原型鏈上則返回true,不然返回false。
用JavaScript來描述instanceof的實現邏輯是這樣的:

JavaScript原型鏈

先給你們看一個JavaScript的原型鏈結構圖。
悄悄告訴你理解原型鏈的小技巧: 將__proto__箭頭視做泛化(子類到父類)關係!
那麼圖中全部的虛線將構成一個繼承層級,而實線表示屬性引用。

圖中給出了Object.prototype.__proto__ == null,但它尚未標準化,在Chrome、Safari和Node.js下它是不一樣的東西。
但能夠看到JavaScript中全部對象的共同隱式原型爲Object.prototype,它的上一級隱式原型是什麼已經不重要了, 由於它不會影響全部內置對象以及用戶定義類型的原型鏈結構。
上圖其實已經解釋了不一樣內置對象instanceof的行爲,咱們來看Function和Object的特殊之處:
  1. Object是由Function建立的:由於Object.__proto__ === Funciton.prototype;
  2. 同理,Function.prototype是由Object建立的;
  3. Funciton是由Function本身建立的!
  4. Object.prototype是憑空出來的!
如今咱們能夠解釋特殊對象的instance行爲了:
另外能夠看到當你聲明一個函數(好比Animal)時,Animal.prototype會自動被賦值爲一個繼承自Object的對象, 並且該對象的constructor等於Animal。即:
值得注意的是Animal若是被Cat繼承,Cat實例(好比cat)的constructor仍然是Animal。

總結

1.每一個函數對象都有一個 prototype 屬性,這個屬性就是函數的原型對象。
2.原型鏈是JavaScript實現繼承的重要方式,原型鏈的造成是真正是靠__proto__ 而非prototype。

好了,今天的講解就那麼多,若是你還有什麼前端問題想提問的,或者你想李老師下次給你們講什麼內容,能夠直接留意提問,說不定下次文章就會講解了。

更多網頁前端開發技術乾貨,行業資訊,面試技巧,歡迎關注前端開發公衆號【網頁前端開發學習】
前端

若是你以爲這篇文章對你有幫助,請轉發點贊支持一下!
相關文章
相關標籤/搜索