換個角度就很好深入理解的js繼承

夜還不夠黑丶發表於2019-09-17
有個小夥子找到我,問我說:“我看了好多遍繼承、原型鏈,但是感覺還是沒懂”
我說:“你有兒子你就懂了”
複製程式碼

目錄

  • 前言
  • 什麼是Prototype
  • 什麼是原型鏈
  • 基礎結構
  • 晉升機構
  • 進階結構
  • 官方結構
  • NEW操作符
  • END

前言

最近在整理生活的過程中,遇到了幾個問題,我身邊的大多數人是不太清楚前端是如何進階的。

比如他不是很明確怎麼才算中級工程師,怎麼才算高階工程師,怎麼算p5,怎麼算p6。所以我在整理一份前端進階體系表(20%)。因為東西實在太多了。舉個例子,類似下面這種。

React

  • 初級要了解裡面生命週期 一些api,一些特性 元件化開發

  • 中級要了解 diff演算法 虛擬dom樹的比對,key值優化問題,render優化,context

  • 高階要了解 觀察者模式、setState週期運作、高階元件,反向繼承屬性代理

如果你覺得你需要的話,請給我留個言,好讓我提速往下寫。否則我就用別人喝咖啡的時間用來打桌球。

在講繼承之前先搞明白幾個概念。

什麼是prototype

是吧,一看到這個問題就頭大。面試的時候百問不爽。 就像問你生命的起源一樣,那你就得跟他從恐龍滅絕開始講到iphone11發售。

話不多說 滿分答案在此。

Javascript裡面都是物件,必須有一種機制,將所有物件聯絡起來。
所以,Brendan Eich最後還是設計了"繼承"。
但是,他不打算引入"類"(class)的概念,因為一旦有了"類",
Javascript就是一種完整的物件導向程式語言了,這好像有點太正式了,
而且增加了初學者的入門難度。考慮到這一點,
Brendan Eich決定為建構函式設定一個prototype屬性。
    ----感謝阮一峰老師
複製程式碼

你從javascript作者創作prototype屬性的角度出發來回答這個問題,無懈可擊。

什麼是原型鏈

滿分答案

當訪問一個物件的某個屬性時,會先在這個物件本身屬性上查詢,
如果沒有找到,則會去它的__proto__隱式原型上查詢,
即它的建構函式的prototype,如果還沒有找到就會再在建構函式
的prototype的__proto__中查詢,這樣一層一層向上查詢就會形
成一個鏈式結構,我們稱為原型鏈
複製程式碼

基礎結構

換個角度就很好深入理解的js繼承

我們來縷一下邏輯,先來對比一下這個繼承的基礎結構。

我舉得例子就是生活中,你兒子繼承你的東西的流程。

  • 你有個房子,然後生了你兒子
  • 如果你想把房子繼承給你兒子使用,必須證明你兒子是你兒子
  • 所以你在你兒子出生的時候,把你兒子的名字寫在了戶口本上,證明你兒子是你兒子,並且,你兒子可以使使用者口的影印件(_ proto _)可以使用者口來使用你的房子,以及一些你兒子不知道的財產(比如三亞有套房你兒子不知道,但是如果你兒子發現了,他使用者口的影印件可以使用那套房子)
  • 戶口是你的,你兒子只有使用權,戶口跟你之間有兩條線

這就是抽象的基礎結構。

晉升結構

換個角度就很好深入理解的js繼承

這時,你兒子很努力的買了一輛車。然後生了個孫子。

我們得走一下家產繼承流程

  • 你兒子把你孫子名字寫在了他的戶口本上
  • 你孫子擁有你兒子戶口本的使用權
  • 你孫子間接獲取了你戶口的使用權
  • 所以-你孫子可以開你兒子的車,住著你的房子。
  • 你不能開你兒子的車。

這樣就可以一代一代傳下去

進階結構

換個角度就很好深入理解的js繼承

這時左邊的例子就有些抽象了,我還沒想好有什麼更貼切的形容方式。

  • 如果你這一代不是繼承父親而來的,那麼直接走祖先
  • 所有戶口本的使用權 都在 公安局檔案庫
  • 公安局檔案庫與公安局之間是兩條線

然而大家可以看出來,我們是可以通過f1 間接找到 Funtion() 以及 Object() 所以會有很多隱藏的線,這些隱藏的線會通過_proto_連線,大家知道這些線是間接繼承先來的就可以了。

官方結構

換個角度就很好深入理解的js繼承

上面這個圖就顯示了最官方的原型鏈的結構圖,也是問我問題那個小夥子百思不得其解的,如果把這個圖抽象成家庭財產繼承問題就沒有那麼困惑了我認為。

這麼看起來,這些箭頭指標的指向可以連線成一條條“鏈子”,就是原型鏈。有點像關係拓撲圖

NEW操作符

我們都知道NEW操作符可以實現建構函式的繼承。 那麼new操作符的原理是什麼呢 我們先看一下程式碼部分

換個角度就很好深入理解的js繼承

使用new命令時,它後面的函式依次執行下面的步驟。

  • 建立一個空物件,作為將要返回的物件例項。
  • 將這個空物件的原型,指向建構函式的prototype屬性。
  • 將這個空物件賦值給函式內部的this關鍵字。
  • 開始執行建構函式內部的程式碼。

在我的理解看來,這就是你拿著戶口本去公安局給你兒子登記的過程。

你仔細想我這句話,越想越有滋味。

END

最近在整理生活,為什麼說是在整理生活,因為方方面面都需要梳理一下。 就像寫文章來說,以前我會用很長很長時間來構思文章結構,中心思路,以及傳穿針引線的知識點。後來我發現,內心在反對這種做事節奏,首先我認為,做事又快又好是萬物的中心思想,快節奏的世界,快餐,快手遊等,都在提速。

就像這篇文章,我寫了兩個小時多一點,但是我寫的開心的不得了,行雲流水,也會對大家有所幫助。

如果做一件事是慢的,我希望他的產出高於投入,然而寫文章這件事情,我希望能在快的基礎上,更好。

至此,給我自己敬個禮,最近辛苦了。

相關文章