- 原文地址:What I learned from reading the Redux source code
- 原文做者:Anthony Ng
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:繆宇
- 校對者:anxsec 輕舞飛揚
我老是聽人說,想拓展開發者自身視野就去讀源碼吧。html
因此我決定找一個高質量的 JavaScript 庫來深刻學習。前端
我選擇了 Redux,由於它的代碼比較少。node
這篇文章不是 Redux 教程,而是閱讀源碼後的收穫。若是你對學習 Redux 感興趣,強烈推薦你去看 Redux 教程,這個系列文章是 Redux 的做者 Dan Abramov 寫的。react
一些新來的開發者常常問我,怎樣纔是最好的學習方式?我每每會告訴他們在項目中學習。android
當你構建一個項目來實踐你的想法時,因爲你對它的熱愛,會讓你度過難熬的 debug 階段,即便遇到困難也不會放棄。這是一個很是神奇的現象。ios
可是一我的閉門造車也是有問題的。你不會注意到你開發過程當中的壞習慣,你也學不到任何最優的解決方案。你可能都不知道又出了哪些新的框架和技術。在獨自寫項目的過程當中,你很快會發現你的技能達到瓶頸。git
只要有可能,我建議你找些小夥伴和你一塊兒開發。github
試想一下,坐在你旁邊的小夥伴(若是你夠幸運,他剛好是個大神),你能夠觀察他思考問題的過程。你能夠看他是如何敲代碼的。你能夠看他是如何解決算法問題的。你能夠學到新的開發工具和快捷鍵。你會學到許多你一我的開發時學不到的東西。算法
斯特拉迪瓦里小提琴。npm
我用斯特拉迪瓦里的小提琴舉個例子。斯特拉迪瓦里小提琴以出色的音質聞名世界,在業界能夠說是一枝獨秀。許多人嘗試用各類方法去解釋爲何它這麼牛逼,從古老教堂搶救出來的木材到特殊的木材的防腐劑。許多人想要複製一把斯特拉迪瓦里小提琴,結果都失敗了,由於他們不知道安東尼·斯特拉迪瓦里究竟是怎麼作的。
設想一下,若是你和安東尼·斯特拉迪瓦里在一個房間裏工做,那麼全部的獨門祕籍你均可以學到。
這下你知道該如何與你的開發小夥伴相處了吧。你只須要安靜的坐他旁邊,看着他寫出一行行斯特拉迪瓦里式的代碼。
對於與多人來講,協同編程是一個很好的機會,能夠經過別人的代碼學到不少東西。
閱讀高質量的代碼就像讀一本精彩的小說同樣,比起直接和做者交流,你可能理解起來比較困難。可是你能夠經過看註釋和代碼,獲取到有價值的信息。
對於那些認爲看源碼沒什麼用的的同窗,你能夠去看一個故事,一個叫比爾·蓋茨的高中生,爲了瞭解某個公司的機密,他甚至去翻人家的垃圾桶找源碼。
若是你也能夠像比爾·蓋茨那樣不厭其煩的看源碼,那還在等什麼?找一個 github 倉庫,看源碼吧!
咦,源碼呢?
閱讀源碼的同時,你也能夠去看官方文檔,官方文檔的結構就像做者寫的代碼同樣,寫得好的官方文檔就讓你彷彿坐在做者旁邊同樣。你也能夠在上面看到別人遇到的問題。官方文檔中的超連接提供了豐富的擴展閱讀的資源。在評論區你還能夠和大神一塊兒交流。
平時我也會在 YouTube 看別人寫代碼,我推薦你們去看SuperCharged 直播寫代碼系列,來自 Google Chrome 開發者的 Youtube 頻道。看兩個 Google 工程師直播寫一個項目,看他們是如何處理性能問題的,和你們同樣,他們也會被本身拼寫錯誤致使的 bug 卡住。
Linting 用於檢查代碼,發現潛在的錯誤。它幫助咱們保持代碼風格的一致性和整潔。你能夠本身定製規則,也能夠用預設的規則(好比 Airbnb 提供的規則)。
Linting 在團隊開發中特別有用。它讓全部代碼看起來像一我的寫的。它能夠強迫開發人員按照公司的代碼風格來寫代碼(同事不用在閱讀代碼上花太多時間)。
Linters 不只僅是爲了美觀,它會讓你的代碼更符合語言特性。好比它會告訴你何時使用 「const」 關鍵字來處理那些沒有被從新賦值的變量。
若是你使用了 React 插件,它會警告你關於組件能夠被重構成無狀態的函數式組件。也是可讓你學習 ES6 語法,告訴你的某段代碼能夠用語法新特性來寫。
在你的項目中輕鬆使用 ESlint:
$ npm install --save-dev eslint
複製代碼
./node_modules/.bin/eslint --init
複製代碼
"scripts": {
"lint": "./node_modules/.bin/eslint"
}
複製代碼
$ npm run lint
複製代碼
查看它們的官方文檔,瞭解更多。
許多編輯器也有插件來檢查你的代碼。
有些時候 Linter 會對一些正確的代碼報錯,好比 console.log。你能夠告訴 Linter 忽略這行代碼,不對其進行檢查。
在 ESlint 中忽略檢查,你能夠這樣寫代碼註釋:
// 忽略一行
console.log(‘Hello World’); // eslint-disable-line no-console
// 忽略多行
/* eslint-disable no-console */
console.log(‘Hello World’);
console.log(‘Goodbye World’);
/* eslint-enable no-console */
複製代碼
在源碼中我發現一個 「isCrushed()」 的空函數,很奇怪。
後來我發現它的目的是爲了檢查代碼是否被壓縮了。在代碼壓縮過程當中,函數名字和變量會被縮寫。當你在開發的時候若是使用了壓縮後的代碼,若是一個條語句被檢測到仍然有 「isCrushed()」 存在,就會有警告提示。
在學習 Redux 源碼以前我不多在代碼中拋異常。JavaScript 是一個弱類型,因此咱們不知道函數中傳入參數的類型。因此咱們必需要像強類型語言那樣對於錯誤要拋出異常。
使用 try…catch…finally
語句來拋出異常。這樣作能夠方便你 debug,以及理清代碼邏輯。
在控制檯中產生的錯誤,能夠很方便堆棧跟蹤。
頗有用的棧跟蹤。
作異常信息處理讓你的代碼邏輯清晰。好比,若是有一個 "add()" 函數,只容許傳入數字,若是傳入的不是數字就要拋出異常。
function add(a, b) {
if(typeof a !== ‘number’ || typeof b !== ‘number’) {
throw new Error(‘Invalid arguments passed. Expected numbers’);
}
return a + b;
}
var sum = add(‘foo’, 2);
// 拋出異常後會終止代碼執行
複製代碼
源碼中有一個 「compose()」 函數,根據已有的函數構建出新的函數:
function compose(…funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
const last = funcs[funcs.length — 1]
const rest = funcs.slice(0, -1)
return (…args) => rest.reduceRight((composed, f) => f(composed), last(…args))
}
複製代碼
若是我有兩個已知的 square 函數和另外一個 double 函數,我能夠把它們組成一個新函數。
function square(num) {
return num * num;
}
function double(num) {
return num * 2;
}
function squareThenDouble(num) {
return compose(double, square)(num);
}
console.log(squareThenDouble(7)); // 98
複製代碼
若是我沒看過 Redux 的源碼,我都不知道還有這種犀利的操做。
當我在看 「compose」 函數的時候,我發現了一個原生數組方法 「reduceRight()」,我以前都沒聽到過。這讓我想知道還有多少我沒聽過的原生方法。
咱們來看一個代碼片斷,一個使用了原生數組方法 「filter()」,一個沒有,經過對比看原生方法存在的價值。
function custom(array) {
let newArray = [];
for(var i = 0; i < array.length; i++) {
if(array[i]) {
newArray.push(array[i]);
}
}
return newArray;
}
function native(array) {
return array.filter((current) => current);
}
const myArray = [false, true, true, false, false];
console.log(custom(myArray));
console.log(native(myArray));
複製代碼
你能夠看到使用 「filter()」 會讓你的代碼變得簡潔。更重要的是,避免了重複造輪子。「filter()」 會被使用上百萬次,比起你本身造輪子,能夠避免不少 bug。
當你想造輪子的時候,先看看你的問題是否已經被原生方法解決了。你會驚喜的發現有很是多的實用方法在你用的編程語言中。(好比,能夠看看 Ruby 的數組的從新排列的方法)
在源碼中,我看到了許多有很長名字的函數。
雖然這函數名讀起來會讓你的舌頭打結,但你能夠清楚的知道這個函數是作什麼的。
在你的代碼中使用描述性的函數名,讓你更多的是讀代碼而不是寫代碼,別人也能夠很輕鬆的閱讀你的代碼。
用較長的描述性函數名帶來的好處遠超過敲擊鍵盤所帶來的快感。現代的文本編輯器都有自動補全功能,它能夠幫助你輸入,因此沒有理由再使用相似 「x」 或者 「y」 的變量名。
不要老是使用 console.log,若是你要拋出異常,請使用 console.error,你能夠在 console 中看到紅色的打印內容和棧的跟蹤。
console.error()
查看 console 文檔,看看其餘的方法。好比計算運行時間的計時器(console.time()),用表格方式打印信息(console.table()),等等。
不要懼怕去讀源代碼。你確定會學到一些東西,甚至能夠爲它貢獻代碼。
在評論中分享你在閱讀源碼中的收穫吧!
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。