如何編寫高質量的函式 -- 命名/註釋/魯棒篇

原始碼終結者發表於2019-02-26

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

此篇我將會從函式的命名、註釋和魯棒性方面,闡述如何編寫高質量的函式。

PS:這一篇相對上一篇文章要簡單好懂多了。

引言

寫第二篇之前,先說個事情。針對前面我寫的 如何編寫高質量的函式 -- 敲山震虎篇 文章的評論區,小夥伴提出的一些問題,我也全部都看了,特此寫了答疑篇。

答疑篇放在了 issues 上,點選下面連結即可 TP :

如何編寫高質量的函式 -- 敲山震虎的答疑篇

對我的回答有什麼疑問的話,可以 issues 討論,這篇文章就不放在掘金了。

PS: 提一下一些公眾號(掘金,奇舞週刊等)轉載的情況,由於文章一開始有錯誤,然後公眾號又沒有同步,然後我又不能幫你們改,於是點開公眾號文章,看著那些還在的錯誤,卻無能為力的心情,心裡默默 ob : 感謝地主們的轉載,那就這樣吧?。

好,胡謅不多說,直接開始吧。

函式命名

從文章開頭的圖片可以知道,命名和快取是電腦科學中的兩大難題。

而今天要說的是函式命名,雖然函式命名涉及到的範圍較窄,但思想都是一樣的,完全 可以借鑑到其他的形式中。

我閱讀過程式碼大全的變數一章,也針對性的閱讀過一些原始碼,比如 lodash , ramda 這些函式工具庫。現在根據我個人的一些感悟,總結了一些我個人認為能幫助你徹底解決命名這個事情的 best practice

PS: 雖然變數命名這個沒有所謂 best practice ,但是對於前端的函式命名來說,我個人認為是可以有一套完善的 best pratice 的, 聽我娓娓道來。

目前前端的函式命名存在什麼問題

存在什麼問題呢?要我說啊,那些業界標準,比如駝峰,首字母大寫的類和建構函式,下劃線,$ 等都不是瓶頸。真正的瓶頸是一些你察覺不到的,或者察覺到但是無能無力的細節。比如:

  • 中英語言的差異性
  • 不懂得從多維度去提升命名的準確性
  • 不會使用輔助工具

下面進行簡明扼要的分析。

PS: 關於駝峰等耳熟能詳的業界標準我就不再提了。

漢語和英語的差異性

為什麼一開始要說這個呢,因為我認為這是目前命名中,存在的最大的問題。英語水平好的哥們沒多少,很多人不能掌握英語命名的那一套語法規則,說白了就是你英語水平達不到能像外國人那樣能寫出符合英語 style 的名字。

為什麼不能用漢語方式命名呢?

理由就三個:

  • 用拼音的本質問題:漢語拼音存在多義性,想想就瑟瑟發抖。
  • 用漢字的問題:雖然輔助工具已經很完善了,但是沒法普及,沒法和國際接軌,說白了就一句話,太小眾了,外國人沒有會的,不跟你玩。
  • 鄙視鏈已經形成(emmmm)。

用英語時遇到的困難

最大的困難就是 不會

我舉個例子,都知道 react 的生命週期吧,如下:

  • componentDidMount

  • componentWillReceiveProps

  • shouldComponentUpdate

很多人都會有疑問,為什麼用 did ,為什麼用 will 。行吧,記住就完事了,然後過了一段時間,面試的被問到了,然後心裡 ob:componentMounted 還是啥來...

多麼鮮活的例子,嗯,繼續往下讀吧,後面有驚(極)為(為)天(驚)人(悚)的答案。

如何讓命名有英語 style

黑人臉,怎麼讓啊?

老哥,多翻翻高中或者初中的英語語法知識吧。比如我舉個最簡單的例子,你就知道了。

componentDidMountreact 等生命週期的鉤子,但是為什麼要這樣命名?

componentWillReceiveProps 為什麼要這樣命名?

答案就在下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

注意上圖中的 did 代表一般過去時,will 代表一般將來時。

然後我們百科一般過去式和一般將來時,然後如圖所示:

一般過去時:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

一般將來時

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

看上圖的紅箭頭,did 表示一般過去時,時是指動作發生的時間,用在這裡,突出了鉤子的含義,一旦 mount 成功就執行此函式。是不是瞬間明白了,好了,will 同理。

啥也別說了,趕緊去好好看看初高中英語語法吧。

通過函式返回結果來命名

這是個小特性,比如 shouldComponentUpdate , 為什麼 should 放在最前面。

因為這個函式返回的值是布林值。那麼我們可以理解為這是個問句,通過問句的形式來告訴我們,這裡具有不確定性,需要根據返回值來判斷是否更新。

關於問句的英語語法,老鐵們還要多翻翻語法書啊(淚)。

藉助工具

藉助谷歌翻譯

谷歌翻譯這個就不說了,大家都會

藉助 codelf

這是一個神器,用來搜尋各種開源專案中的變數命名,來給你提供參考。

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

地址:unbug.github.io/codelf/

對應名字的 VSCODE 外掛也有,具體怎麼用,小夥伴自行去了解吧。

如何避免函式命名的多義性和不可讀性

可能你給一個函式命名了,其他人看到這個函式時,一臉懵逼,完全不知道這命名的啥子東西喲,只能靠猜。

比如我從 ramda 原始碼中找了一個函式,程式碼如下:

var forEachObjIndexed = _curry2(function forEachObjIndexed(fn, obj) {
  var keyList = keys(obj);
  var idx = 0;
  while (idx < keyList.length) {
    var key = keyList[idx];
    fn(obj[key], key, obj);
    idx += 1;
  }
  return obj;
});
export default forEachObjIndexed;

複製程式碼

這個函式叫 forEachObjIndexed ,看到這個命名,是不是一臉懵逼,反正我第一次看到是懵逼了,這啥子嘛,什麼鬼東西,然後我就去趴了下原始碼,從原始碼裡面的函式註釋中才知道是幹啥的,函式註釋如下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

看到沒,多詳細,當然,這是為了輸出文件用的,但是給了我們一起非常好的解決方法。那就是:

如果你實在想不到如何去命名,或者你自己已經知道這個命名很爛了,比如太長,比如很難理解,那這個時候你就別掙扎了。寫一個你覺得還 ok 的命名,然後把剩下的時間留給你寫註釋吧。比如 forEachObjIndexed 的第一部分的註釋就是對整個函式的整體介紹和說明。

如果你的函式命名很爛,那這個時候,函式的整體介紹和說明就顯得非常重要了。這部分你一定要做好,英語水平不好的話,那就老老實實寫中文。這部分做好了,這個函式你哪怕用兩行文字命名的,或者用了火星文命名的,也沒關係,問題不大。

函式命名的分類

最後說一說命名的分類,這是我個人的一些看法。

為什麼我會說函式命名的分類呢,是因為我們經常會看到函式會這樣命名(原始碼中很普遍)。比如:

- $xxx()
- _xxx()
複製程式碼

這種帶各種字首的函式名,看起來並不好看。這樣命名,在我個人看起來是非常彆扭的,但是為什麼要有這種命名呢,其實這是前端的無奈之舉。

核心原因就是 JS 語言不支援私有變數,導致只能使用 _ 或者 $ 來保證相應的對外不可見,通過治標不治本的方法來解決這個問題。

所以我把前端的函式命名分為兩大類,如下:

第一類:不想暴露給外部訪問的函式(比如只給內部使用)

第二類:暴露給外部訪問的函式(各種功能方法)

我個人目前的觀點,大致也就這兩大類了。

PS:這裡我沒把 Symbol 初始化的函式命名考慮在內,比如如下程式碼:

const ADD = Symbol('add')

[ADD](a, b) {
  console.log('a + b')
}
複製程式碼

關於 Symbol 的用法,大家可以自行了解,這種特例我就不考慮在內了。

PS:關於這個無奈之舉,在瞭解的更多的時候,會發現在前端,並沒有什麼方法(設計模式也好,hack 方法也好)能絕對的解決上面的問題,所以有時候你不得不使用 _ 等,因為當都不能解決這個問題的時候,那越簡單的方式越受歡迎,這就是現實。

總結

總結一下最佳實踐:

多學習初中高中英語語法,開源專案中的函式命名沒有那麼難理解,通過語法的學習和藉助工具,函式命名基本可以解決,如果遇到無法清晰描述所寫函式的目的的命名時,請務必給函式寫上良好註釋,不管函式名字有多長多難懂,只要有良好的註釋,那就是可以接受的一件事情。畢竟你也不想命名的這麼難懂啊,但是能力有限,那就用漢語做好註釋吧,這樣的效果也是槓槓的。

如何通過良好的函式命名來提供函式的質量,我也說的差不多了,答案都在文字中,如何去借助工具,如何去理解英語中的命名語法,如何去通過多維度來增加命名含義的準確性和可讀性。簡單聊了下目前前端界函式命名的分類,大家自行體會和運用吧。

PS:一些都知道的點我就不說了,比如動詞+名詞,名詞+動詞,駝峰等,清晰描述函式的目的,這都不是痛點,痛點我都說了,最佳實踐也說了。

函式的註釋

我們來談函式的註釋,註釋一方面提高了可讀性,另一方面也可以通過註釋去做一些其它的事情,比如生成線上文件。一個高質量的函式,註釋少不了的,但是這並不代表所有的函式都需要註釋。富有富的活法,窮有窮的瀟灑,重要或者說複雜的函式,那就給個好註釋,簡單或者不重要的函式,可以不給註釋或者給一個簡單的註釋。說空話沒有意義,我們來看看目前函式的註釋都有哪幾種方式。

PS:這裡要注意我上面的用詞,如果你覺得這個函式命名很爛,那你就應該給一個好的註釋。

先說一些有名的npm包的一些註釋風格

就像大學裡面寫論文之前,都要閱讀很多文獻資料,我們也一樣,我們來看看幾個有名的 npm 包是怎麼玩註釋的。

egg.js 的註釋風格

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

從圖中,我們看到 egg.js 的入口檔案的註釋情況,暫且不去判斷這是不是一種 doc 工具的註釋規則(不要在意細節)。我們就看一下其註釋特點,是不是發現和你腦海中的註釋風格又有區別了呢。這種入口檔案的註釋特點,簡單整潔,這種思想是不是要吸收一波,以後你做開源專案的時候,這些思想都可以帶給你靈感。

繼續看下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

這是一個被抽象出來的基類,展示了作者 [Yiyu He] 當時寫這個類的時候,其註釋的風格。從這張圖中,我們能學到什麼呢?有以下幾點:

第一點:建構函式的註釋規則,表示式語句的註釋規則。

第二點:註釋的取捨,有一些變數可以不用註釋,有些要註釋,不要有那種要註釋就要全部註釋的思想。

再看兩張有趣的圖片:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

看上面兩張圖的箭頭,指向的都是同一個作者 [fengmk2] , 我們看他的函式註釋規則。體會一下不同,想想為什麼第一張圖沒有空格,第二種有空格,還有對返回的 this 的註釋,比如很多人習慣將 this 直接註釋成 Object 型別。

lodash.js

說到函式註釋,就不能不說到 lodash.js 。但是寫到這,我發現這塊要是加上去的話,第二篇的文字就又超了,那這裡就不再說了,大家自己看看原始碼分析一下吧(這操作真香)。

通過註釋生成線上文件的思考

有人說註釋要很規範,方便給別人,比如用 jsdoc 等 。這裡我個人的看法是這樣的,對一些不需要開源的 web 專案,沒有必要用 jsdoc , 理由如下:

  1. 繁瑣,需要按照 jsdoc 規則來
  2. 個人認為,jsdoc 有入侵性,文件規則需要寫在程式碼中。

這裡我認為如果要寫註釋說明手冊,對於大型專案,我推薦使用 apidoc , 因為 apidoc 入侵性不強,不要求把規則寫在程式碼中,你可以把所有規則寫到一個檔案中。具體使用方法,我就不說了,自行搜尋相關資料。

但是一般小專案,沒有必要單獨寫一份 api 文件。如果是開源的大型專案,那你要考慮的事情就更多了,首先需要有開源的官方網站,你會看到網上的一些開源專案官網好像很酷,其實這個世界上不缺的就是輪子,你也可以很快的做出這樣的網站,下面我們來看看是如何做到的。

首先我們看一下 taro 原始碼,會發現如下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

這裡就是生成一個靜態網站的祕密,執行這個 npm run docs 就可以了。用到的是 docusaurus 包,不知道的可以自行搜尋。

然後這裡你看下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

從圖中可以知道,文件的內容,來源於 docs 目錄,裡面都是 md 檔案,開源專案的文件說明都在這裡。

當然也有把對應的文件直接放到對應的程式碼目錄下的,比如 ant-design 如下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

就是直接把文件放在元件目錄下了。

從這裡,我們可以知道,目前流行的開源專案的官方網站是怎麼實現的,以及文件該怎麼寫。你可以說這和函式註釋沒有什麼關係,但是想想好像又有點關係,這裡就不多言了,自己體會吧。

我個人的註釋習慣

下面說說我本人對函式註釋(只針對函式註釋)的一些個人風格或者意見。

分享 VSCode 關於註釋的幾個工具

  • Better Comments 給註釋上色
  • Document This 自動生成註釋
  • TODO Highlight 高亮 TODO ,並可以搜尋所有 TODO

具體用法就不說了,下面是一張演示圖,自行去研究吧:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇


寫和不寫註釋的平衡

我個人的觀點是這樣的:

不影響可讀性,複雜度低,對外界沒有過度干涉的函式可以不寫註釋。

表示式語句的註釋

函式內,表示式語句的註釋可以簡單點,我一般如下圖所示,// 後面加簡要說明。

function add(a, b) {
  // sum ....
  let sum = a + b
}
複製程式碼

TODO 註釋

function say() {
  // TODO: 編寫 say 具體內容
  console.log('say')
}
複製程式碼

FIXME 註釋

function fix() {
  // FIXME: 刪除 console.log方法
  console.log('fix')
}
複製程式碼

函式註釋

一般我分為普通函式和建構函式。

普通函式註釋:

/**
 * add
 * @param {Number} a - 數字
 * @param {Number} b - 數字
 * @returns {Number} result - 兩個整數之和
 */
function add(a, b) {
  // FIXME: 這裡要對 a, b 引數進行型別判斷
  let result = a + b
  return (result)
}
複製程式碼

建構函式註釋:

class Kun {
  /**
   * @constructor
   * @param {Object} opt - 配置物件 
   */
  constructor(opt = {}) {
    // 語句註釋
    this.config = opt
  }
}
複製程式碼

總結

從開源專案的程式碼中可以發現,註釋的風格多種多樣,有時候我自己不同專案的註釋風格也有點差別,但是我會盡可能的去平衡註釋和不註釋,上面註釋的基本原則還是要遵守的。

但是怎麼說呢,註釋這塊不存在銀彈。

函式的魯棒性(防禦性程式設計)

大家都聽過防禦性程式設計對吧,let it crash 。 我們看一個段子,下圖:

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

看最後一句,測試測了那麼多場景,最後酒吧還是炸了(哈哈哈哈哈哈怎麼回事?)。

所以,我們可以看出,防禦性程式設計的核心就是:

把所有可能會出現的異常都考慮到,並且做相應處理。

但是我個人認為,防禦性的程度要看其重要的程度。一般來說,不可能去處理所有情況的,但是提高程式碼魯棒性的有效途徑就是進行防禦性的程式設計。

一個專案的思考

我接手過一個需求,重寫(完全重構)蘇寧易購微信小程式的登入註冊繫結的功能,並將程式碼同步到蘇寧其他小程式(和其他小程式的開發進行程式碼交接並協助 coder 平穩完成版本過渡)。

這個專案重要性不言而喻,由於使用者的基數很大,風險程度很高,需要考慮很多場景,比如:

  1. 支不支援線上版本回退,也就是需要有前端的 AB 版本方案(線上有任何問題,可以快速切到舊登入方案)

  2. 需要有各種驗證:圖形驗證碼、簡訊驗證碼、ip 、人機、裝置指紋、風控、各種異常處理、異常埋點上報等。

  3. 程式碼層面的考慮:通過程式碼優化,縮短總的響應時間,提高使用者體驗。

  4. 如何確保單個節點出問題,不會影響整個登入流程。

你會發現,需要考慮的點很多,如何去合理的完成這個需求還是比較有難度的。

PS: 關於第四點的如何確保單個節點出問題,不會影響整個登入流程,文末有答案。

下面我就關於函式魯棒性,說一說我個人的一些看法。

前端函式魯棒性的幾種方式

入參要魯棒性

ES6 的到來後,函式的入參寫法已經得到了質的提高和優化。看下面程式碼

function print(obj = {}) {
  console.log('name', obj.name)
  console.log('age', obj.age)
}
複製程式碼

print 函式,入參是 obj 通過 obj = {} 來給入參設定預設的引數值,從而提高入參的魯棒性。

但是你會發現,如果入參的預設值是 {} ,那函式裡面的 obj.name 就會是 undefined ,這也不夠魯棒,所以下面就要說說函式內表示式語句的魯棒性了。

函式內表示式語句要魯棒性

繼續上個例子:

function print(obj = {}) {
  console.log('name:', obj.name || '未知姓名')
  console.log('age:', obj.age || '未知年齡')
}
複製程式碼

如果這樣的話,那你會發現表示式語句就變得比較魯棒性了,但是還不夠好,這樣寫不夠抽象,我們換種方式稍微把表示式語句給解耦一下,程式碼如下:

function print(obj = {}) {
  const { name = '未知姓名', age = '未知年齡' } = obj
  console.log('name:', name)
  console.log('age:', age)
}
複製程式碼

這樣的話,看起來就感覺好多了,其實還可以再抽象,比如吧 console.log 封裝成 log 函式,通過呼叫 log(name) ,就能完成 console.log('name:', name) 的功能, 這裡就不再說了,自行研究吧。

函式異常處理的兩個層面

上面的那幾個點,我個人認為可以歸類到一個方案層面去,那就是:

防患於未然,從一開始就不要讓異常發生。

但是不要忘了,總會有萬一,還有一個方案層面要去考慮,那就是:

異常還是出現了,該怎麼去處理出現的異常。

下面兩個層面已經確定了,那如何去更好的處理各種異常,提高函式的魯棒性呢,我個人有以下幾點看法。

推導一下 try/catch 的原理

有很多人不清楚怎麼去用 try/catch 。這裡我來按照我個人的見解,來推一下其原理吧,首先 js 是執行在 node.js 提供的執行時環境中的,而 node.js 是用 C++ 寫的。C++ 是有自己的異常處理機制的,也是有 try/catch 的 。那就說明 jstry/catch 的底層實現是直接通過橋,呼叫 C++try/catch

C++try/catch 具有的一些特性,大家可以自行去了解一下,比如其中就有一個特性是這樣的:

try/catch 只能捕捉當前執行緒的異常。

所以這也就很好的解釋了,為什麼 JStry/catch 只能捕捉到同步的異常,而對於非同步的異常就無能為力了(因為非同步是放在另一個執行緒中執行的)。

這裡是我的推導,不代表確切答案。

這裡我推薦一篇部落格:

C++中try、catch 異常處理機制

有興趣的可以看看。

合理的處理異常

這裡有幾個方法:

第一個方法:如果是同步的操作,可以用 throw 來傳遞異常

看下面程式碼:

try {
  throw new Error('hello godkun, i am an Error ')
  console.log('throw 之後的處程式碼不執行')
} catch (e) {
  console.log(e.message)
}
複製程式碼

首先我們要知道 throw 是以同步的方式傳遞異常的,也就是 throw 要和使用 throw 傳遞錯誤的函式擁有相同的上下文環境。

如果上下文環境中,都沒有使用 try/catch 的話,但是又 throw 了異常,那麼程式大概率會崩潰。

如果是 nodejs ,這個時候就應該再加一個程式級的 uncaughtException 和 來捕捉這種沒有被捕捉的異常。通常還會加上 unhandledRejection 的異常處理。

第二個方法:如果是非同步的操作

有三種方式:

  1. 使用callback ,比如 nodejserror first 風格

  2. 對於複雜的情況可以使用基於 Event 的方式來做,呼叫者來監聽物件的 error 事件

  3. 使用 promiseasync/await 來捕捉異常

現在的問題是,怎麼去選擇哪個方式呢?有這幾個原則:

  1. 簡單的場景,直接使用 promiseasync/await 來捕捉異常

  2. 複雜的場景,比如可能會產生多個錯誤,這個時候最好用 Event 的方式

第三個方法:如果既有非同步操作又有同步操作

怎麼辦呢?這個時候,我個人認為,最好的方式,就是使用最新的語法:async/await 來結合 promisetry/catch 來完成對既有同步操作又有非同步操作的異常捕捉。

第四個方法:處理異常的一些抽象和封裝

對處理異常的函式進行抽象和封裝也是提高函式質量的一個途徑。如何對處理異常進行抽象和封裝呢?有幾個方式可以搞定它:

  • 第一個方式:對 nodejs 來說,通常將異常處理封裝成中介軟體,比如基於 express/koa 的異常中介軟體,通常情況下,處理異常的中介軟體要作為最後一箇中介軟體載入,目的是為了捕獲之前的所有中介軟體可能出現的錯誤

  • 第二個方式:對前端或者 nodejs 來說,可以將異常處理封裝成模組,類似 Event 的那種。

  • 第三種方式:使用裝飾器模式,對函式裝飾異常處理模組,比如通過裝飾器對當前函式包裹一層 try/catch

  • 第四種方式:使用函數語言程式設計中的函子( Monad )等來對異常處理進行統一包裹,這裡 的 Monadtry/catch 在表現上都相當於一個容器,這是一個相當強大的方法。從 Monad 可以擴充套件出很多異常處理的黑科技,但是我建議慎用,因為不是所有人都能看懂的,要考慮團隊的整體技術能力,當然一個人的話,那就隨便嗨了。

合理的處理異常,需要能確定使用哪一種方式來處理異常,我大致也說了具體的選擇情況,這裡我推薦一篇部落格:

Callback Promise Generator Async-Await 和異常處理的演進

目前我見到的講的最全的處理異常的部落格,但我這裡說的都是我認為比較重要的主要的點,兩者還是有明顯區別的,大家融合一下吸收吸收吧。

如何確保單個節點出問題,不會影響整個登入流程

比如登入流程需要4個安全驗證,按照通常的寫法,其中一個掛了,那就全部掛了,但是這不夠魯棒性,如何去解決這個問題呢。這裡我提一下,可能很多人都不會注意到。

主要方案就使用將 promise 的鏈式寫法換一種方式寫,以前的寫法是這樣的:

虛擬碼如下:

auth().then(getIP).then(getToken).then(autoLogin).then(xxx).catch(function(){})
複製程式碼

經過魯棒調整後,可以改成如下寫法:

虛擬碼如下:

auth().catch(goAuthErrorHandle).then(getIP).catch(goIPErrorHandle).then(function(r){})
複製程式碼

經過微調後的程式碼,直接讓登入流程的魯棒性提升了很多,就算出錯也可以通過錯誤處理後,繼續傳遞到下一個方法中。

我個人對異常處理的看法

我個人認為對異常的處理,還是要根據實際情況來分析的。大概有以下幾點看法:

要考慮專案可維護性,團隊技術水平

我曾在一個需求中,使用了諸如函子等較為抽象的處理異常的方法,雖然秀了一把(作死),結果導致,後續這塊的需求改動,還得我自己來。嗯,就是這麼刺激,因為同事不熟悉函數語言程式設計。

要提前預估好專案的複雜性和重要性。

比如在做一個比較重要的業務時,一開始沒有想到異常處理需要這麼細節,而且一般第一版的時候,需求並沒有涉及到很多異常情況處理,但是後續需求迭代優化的時候,發現異常情況處理是如此的多,直接導致需要重寫異常處理相關的程式碼。

所以以後在專案評估的時候,要學會嘗試根據專案的重要性,來提前預留好坑位。

這也算是一種面對未來的程式設計模式。

總結

關於函式的魯棒性(防禦性程式設計),我介紹了很多東西,基本上是前端或者是 nodejs 處理異常的常規方法吧。處理異常不是一個簡單的活,工作中還得結合業務去確定合適的異常處理方式,總之,多多實踐出真知吧。

備註

  • 本篇文章閱讀起來就比較輕鬆了,難度不大,細細體會一下會有一些收穫的。
  • 可能講解的不全,如果有什麼遺漏的,歡迎在評論區分享,一起進步。
  • 魯棒性這塊,我沒有提單元測試,字數不夠寫了,再寫文章又很長了,單元測試我只推薦 Jest ,按照官網文件來,本著函數語言程式設計的思想,問題不大。

往屆精品文章

可以這麼說,讀了這篇文章,你的 gitgerrit 就沒有什麼問題。

初中高階的 git 和 gerrit 技巧【大型專案實戰總結 && CR 經驗】


關於如何閱讀 npm 包原始碼的故事。

不敢閱讀 npm 包原始碼?帶你揭祕 taro init 背後的哲學

彩蛋

最近剛寫的一篇文章,發現沒什麼閱讀量,但是我覺得我寫的很好啊,這篇文章絕對會對絕大多數前端工程師有所啟發和幫助。

宣傳一波,想啟發更多還在路上的前端小夥伴:

新時代下前端工程師的推薦書籍和必備知識

交流

加上本篇,這個系列已經寫了兩篇了,我計劃三篇搞定,但是看這情況,後面都是硬貨,很難 7000 字以內搞定呀,後續幾篇搞定,我再 ob 一下吧。

小夥伴們可以關注我的掘金部落格或者 github 來獲取後續的系列文章更新通知。

掘金系列技術文章在 github 上彙總如下,覺得不錯的話,點個 star 鼓勵一下,我將 使命必達 ,持續輸出精品文章。

github.com/godkun/blog

我是原始碼終結者,歡迎技術交流。

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

也可以進 前端狂想錄群 大家一起頭腦風暴。有想加的,因為人滿了,可以先加我好友,我來邀請你進群。

如何編寫高質量的函式 -- 命名/註釋/魯棒篇

風之語

最後:尊重原創,轉載請註明出處哈?

相關文章