自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我從讀源碼中收獲到了什么?閱讀源碼那點小事

開發(fā) 前端
說到源碼,大家腦海里可能浮現(xiàn)出四個字 我太難了。讀源碼貌似和我們遙不可及,因為在日常工作中,我們基本掌握在熟練的程度上,就能夠滿足工作需求,即便是想看源碼,也會被源碼復(fù)雜的邏輯拒之門外,成為了我們心中揮之不去的陰影。

 [[387379]]

本文轉(zhuǎn)載自微信公眾號「前端Sharing」,作者前端Sharing 。轉(zhuǎn)載本文請聯(lián)系前端Sharing公眾號。

一 前言

說到源碼,大家腦海里可能浮現(xiàn)出四個字 我太難了。讀源碼貌似和我們遙不可及,因為在日常工作中,我們基本掌握在熟練的程度上,就能夠滿足工作需求,即便是想看源碼,也會被源碼復(fù)雜的邏輯拒之門外,成為了我們心中揮之不去的陰影。那么我們真的有必要閱讀源碼嗎?我以一個過來人的角度看,答案是肯定的,閱讀源碼不只是停留在源碼層面,它還會帶來一些附加的價值 。

筆者讀過很多源碼,比如 主流前端框架 vue2.0,vue3.0 ,react,node框架 express , koa,和它們衍生生態(tài) react-router,react-redux , dva 等等。要說在閱讀源碼的過程,痛苦么?我感覺過程是痛苦的,但是讀完之后,就會感覺收獲頗豐,感覺付出都是值得的。接下來我們一起探討一下,閱讀源碼那些事。

二 為什么讀源碼?

1 為了面試

一場面試題的思考?

假設(shè)這是一場面試。

面試官:說一下vue2.0響應(yīng)式原理 ?

第一位應(yīng)聘者:object.defineproperty()攔截器屬性,攔截set, get。

打分:4-5分 這樣的答案似乎很難說服我,只能證明面試者對這個知識點有備而來。

第二位應(yīng)聘者:在第一位基礎(chǔ)上,說出了收集依賴的dep對象,負責(zé)渲染更新的渲染watcher,遞歸響應(yīng)式等等,并能夠介紹它們的原理和作用。

打分:6-7分 這樣的答案,已經(jīng)很符合標準了,至少說了vue響應(yīng)式的核心,說明應(yīng)聘者至少深入了解過。

第三位應(yīng)聘者:一方面從初始化 data 開始,到解析 template 模版,進行依賴收集。另一方面能夠從 data 改變,通知渲染 watcher 更新,到頁面變化,把整個流程說明白。

打分:8-10分 這樣的答案,是非常完美的,能夠從源碼角度入手,說明應(yīng)聘者很深入原理,讀過源碼。

從一道面試題,就能看出一個應(yīng)聘者的對于框架的認知程度。而閱讀源碼就是從底層開始全方面認識框架的最佳方式。而且如果把源碼搞得明明白白??梢宰屆嬖嚬俟文肯嗫础I踔聊軌?lsquo;吊打’面試官????。

2 更清晰的運用框架

閱讀源碼的過程中,能夠了解底層是怎么運作的。如果在工作中遇到某些問題,如果讀過源碼,就會找到辦法,問題也就會迎刃而解。

一個bug案例引發(fā)的思考 之前見有同事遇到過這么一個問題。

  1. <el-select v-model="value" > 
  2.   <el-option   
  3.     v-for="(item,index) in list"  
  4.     :key="index"  
  5.     :value="item.value" 
  6.     :label="item.label" 
  7.    /> 
  8. </el-select

 

可能業(yè)務(wù)場景要比這個復(fù)雜,大致是如上這么樣的。出現(xiàn)一個問題就是,每次改變 list ,然后重新選擇 option 的時候,會發(fā)現(xiàn)綁定的 value 數(shù)據(jù)改變了,但是視圖沒有發(fā)生變化。

如果沒有對 vue 中 diff 算法有一定了解,肯定會對這個現(xiàn)象一臉蒙蔽,明明數(shù)據(jù)已經(jīng)改變了,但是視圖為什么沒有變呢?what?

如果看過 diff 算法,和子節(jié)點 patch 過程的同學(xué),就會發(fā)現(xiàn),這個問題主要來源于,用 index 作為 key ,在一次更新中,雖然數(shù)據(jù)改變了,但是根據(jù) index,復(fù)用了錯誤的元素節(jié)點,導(dǎo)致了視圖和數(shù)據(jù)不對應(yīng)的情況。

對于框架或者開源庫,如果我們在使用中遇到了問題,與其在 GitHub 提 issue 等待解決,不如親自去看看源碼,也許答案就在其中。正所謂驀然回首,那人卻在燈火闌珊處。

3 提高編程能力,拓展知識盲區(qū)

我個人覺得,閱讀源碼絕對是提高編程能力,拓展知識點的捷徑。為什么這么說。我們先看兩短經(jīng)典的代碼片段:

no 1 redux compose

  1. export default function compose(...funcs) { 
  2.   if (funcs.length === 0) { 
  3.     return arg => arg 
  4.   } 
  5.   if (funcs.length === 1) { 
  6.     return funcs[0] 
  7.   } 
  8.   return funcs.reduce((a, b) => (...args) => a(b(...args))) 

這是前端領(lǐng)域經(jīng)典的中間件案例,代碼精簡,卻堪稱神來之筆。我們可以學(xué)習(xí)源碼中的,編程手法,即使寫不出如上這么經(jīng)典函數(shù),也能明白什么時候使用繼承,什么時候用閉包。

在閱讀源碼過程中,會有很多高級用法和我們很少用到 api , 我們可以有效對知識點進行掃盲。

  1. vue3.0 /reactivity/src/reactive.ts 
  2.  
  3. const rawToReactive = new WeakMap<anyany>() 
  4. const reactiveToRaw = new WeakMap<anyany>() 
  5. const rawToReadonly = new WeakMap<anyany>()  
  6. const readonlyToRaw = new WeakMap<anyany>() 

vue3.0 中做保存依賴收集關(guān)系的幾個 WeakMap ,引發(fā)了我對 WeakMap 以及垃圾回收機制的思考? WeakMaps 保持了對鍵名所引用的對象的弱引用,即垃圾回收機制不將該引用考慮在內(nèi)。只要所引用的對象的其他引用都被清除,垃圾回收機制就會釋放該對象所占用的內(nèi)存。也就是說,一旦不再需要, WeakMap 里面的鍵名對象和所對應(yīng)的鍵值對會自動消失,不用手動刪除引用。

閱讀源碼,一方面有助于我們寫出詩一樣的代碼,另一方面,擴充了我們的知識面??傊?,真香!

4 培養(yǎng)設(shè)計思維和架構(gòu)能力

優(yōu)秀的源碼有著縱覽大局,運籌帷幄的思維,和中流砥柱的架構(gòu)能力,這對一個正在進階或者正打算進階的工程師來說,是最缺少的。

也許你瘋狂的補習(xí)這知識點,瘋狂看這博客,瘋狂刷著編程題,但是接手一個大的工程項目的時候,還是會手足無措,最后搞得一塌糊涂。這是為什么呢,也許就真的是缺少那么一丟丟設(shè)計思維和架構(gòu)能力。

人生的三種境界和閱讀源碼的三種境界是一樣的。慢慢的自己編程能力會受到潛移默化的影響。

當(dāng)你剛開始看源碼的時候,看自己的代碼還是自己的代碼。但是慢慢的,你會發(fā)現(xiàn)自己寫的代碼,受到了源碼的影響,已經(jīng)不像是自己最初的樣子,當(dāng)你日復(fù)一日的堅持,你就會明白源碼真正架構(gòu)設(shè)計,并能夠自己設(shè)計架構(gòu),代碼中有了自己的靈魂,你會發(fā)現(xiàn)自己的代碼還是自己的代碼,原因是自己進步了,能夠有能力去把控全局。

三 怎么樣讀源碼

上面講述了閱讀源碼的好處,接下來我們講一講怎么有效閱讀源碼。

1 化整為零

冰凍三尺,非一日之寒,閱讀源碼也不是一朝一夕的事情,我們要有計劃的去閱讀源碼。一天抽出時間看一點,然后重點記筆記,可以是 md,可以是手寫的筆記,總之要把核心內(nèi)容記錄下來,因為一是好記性不如爛筆頭,可以加深我們的印象。二是在每次閱讀之前,都把上一次的筆記拿出來看看,做到完美的銜接。把整個源碼分割成多個模塊,一點點去消化,不要想著一口氣把源碼看完,這個是不現(xiàn)實的。

這是筆者在做vue3.0源碼閱讀解析過程中記錄的筆記。

在react 源碼閱讀解析過程中,記錄的筆記:

2 三思而后行

這個是筆者閱讀源碼的精髓所在。三思而后行,在閱讀源碼的時候先問幾個為什么?帶著問題去看源碼會起到事半功倍的效果,為什么這么說呢?如果不帶著問題閱讀,就會處于一種無目標,盲目的狀態(tài),在這種狀態(tài)下,尤其看無聊和繁瑣的源碼,就會精力不集中,長時間就會犯困,無法堅持下去。

在閱讀源碼之前,首先想幾個問題,帶著這幾個問題去源碼中找答案,

例子一:

vue3.0響應(yīng)式原理之前,先提幾個問題:

  • 1 vue3.0怎么構(gòu)建的響應(yīng)式,reactive API到底做了什么?
  • 2 effect 和 reactive 是什么關(guān)系?effect 如何取代 watcher ?
  • 3 如何收集的依賴?
  • 4 通過 this.a 改變,是怎么做到視圖對應(yīng)更新的。

例子二

在閱讀 react-redux 的時候,我會先提這么幾個問題:

  • 1 為什么要在 root 根組件上使用 react-redux 的 Provider 組件包裹?
  • 2 react-redux 是怎么和 redux 契合,做到 state 改變更新視圖的呢?
  • 3 provide 用什么方式存放當(dāng)前的 redux 的 store, 又是怎么傳遞給每一個需要訂閱 state 的組件的?
  • 4 connect 是怎么樣連接我們的業(yè)務(wù)組件,然后更新已經(jīng)訂閱組件的呢?
  • 5 connect 是怎么通過第一個參數(shù)mapStateToProps,來訂閱與之對應(yīng)的 state 的呢?
  • 6 connect 怎么樣將 props,和 redux的 state 合并的?

帶著這些問題去閱讀源碼,就會在源碼中仔細去尋找這些問題的答案,如果找到了答案,并解釋了原理,也會有不錯的成就感。

3 提煉精髓

這一步對于閱讀源碼也是非常重要的,我們要學(xué)會提煉源碼的精髓,以 react 為例子,react 個別函數(shù),可能幾百行,甚至上千行,但是除去服務(wù)端渲染,開發(fā)環(huán)境的警告 __dev__ ,context 上下文的處理,和一些判斷等等,真正的核心邏輯代碼,也許就那么幾行和十幾行,所以我們不需要去扣源碼中的每一行代碼,只需要搞清楚核心邏輯就好。

我們拿react源碼為例子:

  1. react/react-reconciler/ReactFiberClassComponent.js 

這個文件下,有一個 constructClassInstance 方法,用于 new 我們的組件實例。這個方法大約有 200 行左右,但是我給它進行提煉之后,代碼如下

  1. function constructClassInstance( 
  2.   workInProgress, //  
  3.   ctor,    // 我們的 component  
  4.   props,  //  組件的 props  
  5. ){ 
  6.   /* 這里實例化 我們的component */ 
  7.   const instance = new ctor(props, context); 
  8.   /* 給當(dāng)前 組件實例 ,掛上 updater 對象,用于組件渲染更新 */    
  9.   adoptClassInstance(workInProgress, instance); 

核心的代碼只有這區(qū)區(qū)幾行,所以在閱讀源碼的流程中,提煉精髓也是十分重要的。

4 真槍實彈

實踐是檢驗真理的唯一標準。如果想搞清楚源碼,不要單獨停留在看的層面,也要真正去跑一遍源碼。這樣一來我們可以在 github ,克隆下來源碼。然后在關(guān)鍵的上下文,可以 debugger 或者 console 。

步驟如下:

從 github 下載文件。

然后進行debugger或者 console。

接下來把源碼單獨抽出來,打包。

放入我們的demo項目進行驗證。

此時我們要改變一下路徑。因為原來我們的 package 是放在 node_modules 中的,現(xiàn)在路徑改了,所以注意路徑問題。

5 因材施教

并不是所有的框架源碼都需要一個固定的模式去解析的。這一點筆者就吃了苦頭。我們先來說一下背景。

筆者在閱讀 vue2.0,采用集中式閱讀,就是從new Vue為入口,然后逐步向代碼深層去挖掘。最后將各個模塊串聯(lián)起來。

在閱讀完vue2.0的核心原理后, 想要以同樣的模式去閱讀 react,發(fā)現(xiàn)此方案根本行不通,因為react 有很多模塊,比如 react, react-reconciler ,react-dom,scheduler,有好幾千個函數(shù)方法,看著看著就蒙蔽了,即使 debugger ,效果也是甚微,無法把各模塊功能串聯(lián)起來,形成體系。

后來,開始閱讀一些大佬的文章,先明白每一塊干了些什么,有什么作用,然后一塊塊的串起來。最后再去閱讀源碼,發(fā)現(xiàn)效果甚佳。

案例: vue 和 react

vue 集中式閱讀源碼

vue 源碼適合集中式閱讀,就是從 new vue() 開始,到初始化 data ,建立響應(yīng)式 ,patch 元素節(jié)點,解析 template 模版,注入依賴,掛載真實 dom ,一氣呵成,一條線串起來。

react 發(fā)散式閱讀源碼

而 react 需要一種發(fā)散式的閱讀方法,就是你需要先明白,reconciler,scheduler,expiration time,請求關(guān)鍵幀等等,具體是干什么的,有什么作用,然后像搭積木一樣,把它們搭起來。

6 水滴石穿

把值得做的事堅持下去,再把堅持做的事努力做好。 既然選擇閱讀源碼,就要堅持下去,筆者剛開始看源碼的時候也是很痛苦,曾經(jīng)幾度想放棄,但是后來按照上面方法,堅持下去,終于養(yǎng)成了好習(xí)慣,現(xiàn)在完全能夠注意力集中的閱讀源碼,而且過程感覺也不像當(dāng)初那么無趣。

聽說過21天效應(yīng),如果一天一天堅持下去,用不了多久就能養(yǎng)成一種閱讀源碼的好習(xí)慣,相信那個時候,我們比如嘗試用一個新的 package 的時候,忍不住先去 github 上拉下源碼瞧瞧。

四 收獲與總結(jié)

關(guān)于收獲

看源碼的習(xí)慣堅持了差不多二年了,收獲感覺還是蠻多的,首先無論是從知識儲備還是編程寫法或者設(shè)計架構(gòu)上,都有很大的進步,也嘗試了寫了自己的開源項目,并下定決心好好維護下去。

rux 一款redux和react-redux狀態(tài)管理工具

react-keepalive-router緩存頁面路由

總結(jié)

以上就是我在閱讀源碼過程中的所感所悟,路漫漫其修遠兮吾將上下而求索,在閱讀源碼的路上,能堅持下來,將會有一片美麗的風(fēng)景。

責(zé)任編輯:武曉燕 來源: 前端Sharing
相關(guān)推薦

2022-03-27 09:06:04

React類型定義前端

2021-04-15 08:15:27

Vue.js源碼方法

2022-10-08 08:01:17

Spring源碼服務(wù)

2015-10-10 16:02:29

2021-01-02 09:48:13

函數(shù)運算js

2017-04-05 16:40:45

2021-02-11 13:30:56

Nodejs源碼c++

2021-03-09 09:55:02

Vuejs前端代碼

2019-11-20 09:00:52

Linux 開發(fā)操作系統(tǒng)

2023-06-21 08:24:46

2013-12-24 10:05:04

memcached

2025-03-21 10:33:22

2013-08-07 16:04:22

2023-02-06 21:58:23

2022-09-09 19:01:02

接口Reader?Spark

2023-04-17 08:19:47

select *MySQL

2024-03-12 00:00:00

RocketMQ服務(wù)端磁盤

2021-10-06 16:21:32

類型對象Typescript

2020-09-07 14:30:37

JUC源碼CAS

2012-02-14 14:05:59

JavaSpring
點贊
收藏

51CTO技術(shù)棧公眾號