成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用JSDoc提高代碼的可讀性

missonce / 560人閱讀

摘要:所以編輯器就會使用一個(gè)在中經(jīng)常出現(xiàn)用來標(biāo)識任意類型的關(guān)鍵字來描述函數(shù)的參數(shù)以及返回值。描述類型的返回值處理現(xiàn)在這個(gè)年代,基本上已經(jīng)普及開來,所以很多函數(shù)的返回值可能并不是結(jié)果,而是一個(gè)。

工作了四年多,基本上都在圍繞著 JavaScript 做事情。  
寫的代碼多了,看的代碼也多了,由衷的覺得,寫出別人看不懂的代碼并不是什么能力,寫出所有人都能讀懂的代碼,才是真的牛X。
眾所周知, JavaScript 是一個(gè)弱類型的腳本語言,這就意味著,從編輯器中并不能直觀的看出這段代碼的作用是什么,有些事情只有等到代碼真正的運(yùn)行起來才能夠確定。
所以為了解決大型項(xiàng)目中 JavaScript 維護(hù)成本高的問題,前段時(shí)間我們團(tuán)隊(duì)開始使用 TypeScript,但是由前幾年所積累下來的代碼,并不是說改立馬都能全部改完的,所以這個(gè)重構(gòu)將是一個(gè)漫長的過程。
在重構(gòu)同時(shí)我們還是需要繼續(xù)維護(hù)原有的 JavaScript 項(xiàng)目的,而 JSDoc 恰好是一個(gè)中間過渡的方案,可以讓我們以注釋的形式來降低 JavaScript 項(xiàng)目的維護(hù)難度,提升可讀性。
作用
本人使用的是 vs code 編輯器,內(nèi)置了對 jsdoc 的各種支持,同時(shí)還會根據(jù)部分常量,語法來推測出對應(yīng)的類型  
可以很方便的在編輯器中看到效果,所以下面所有示例都是基于 vscode 來做的。

首先,JSDoc 并不會對源碼產(chǎn)生任何的影響,所有的內(nèi)容都是寫在注釋里邊的。
所以并不需要擔(dān)心 JSDoc 會對你的程序造成什么負(fù)面影響。

可以先來看一個(gè)普通的 JavaScript 文件在編輯器中的展示效果:

很顯而易見的,編輯器也不能夠確定這個(gè)函數(shù)究竟是什么含義,因?yàn)槿魏晤愋偷膬蓚€(gè)參數(shù)都可以進(jìn)行相加。
所以編輯器就會使用一個(gè)在 TypeScript 中經(jīng)常出現(xiàn)用來標(biāo)識任意類型的 any 關(guān)鍵字來描述函數(shù)的參數(shù)以及返回值。

而這種情況下我們可以很簡單的使用 JSDoc 來手動描述這個(gè)函數(shù)的作用:

實(shí)際上有些函數(shù)是需要手動指定@return {TYPE}來確定函數(shù)返回值類型的,但因?yàn)槲覀兒瘮?shù)的作用就是通過兩個(gè)參數(shù)相加并返回,所以編輯器推算出了函數(shù)返回值的類型。

對比上下兩段代碼,代碼上并沒有什么區(qū)別,也許有人會嗤之以鼻,認(rèn)為代碼已經(jīng)足夠清晰,并不需要額外的添加注釋來說明。
這種盲目自信一般會在接手了其他人更爛的代碼后被打破,然后再反思自己究竟做錯(cuò)了什么,需要去維護(hù)這樣的代碼。

亦或者我們來放出一個(gè)稍微復(fù)雜一些的例子:

看似清晰、簡潔的一個(gè)示例,完全看不出什么毛病 _除了兩個(gè)異步await可以合并成一個(gè)_。
確實(shí),如果這段代碼就這么一直躺在項(xiàng)目中,也不去改需求,那么這段代碼可以說是很完美的存在了。
如果這段代碼一直是寫下這段代碼的作者在維護(hù),那么這段代碼在維護(hù)上也不會有什么風(fēng)險(xiǎn)。

不過如果哪天這段代碼被交接了出去,換其他的小伙伴來維護(hù)。
那么他可能會有這么幾個(gè)疑問:

getUserInfo的返回值是什么結(jié)構(gòu)

createOrder的返回值又是什么結(jié)構(gòu)

notify中傳入的兩個(gè)變量又都是用來做什么的

我們也只能夠從notify函數(shù)中找到一些線索,查看到前兩個(gè)函數(shù)所返回對象的部分屬性, _但是仍然不能知道這些屬性的類型是什么_。
而想要維護(hù)這樣的一段代碼,就需要占用很多腦容量去記憶,這實(shí)際上是一個(gè)性價(jià)比非常低的事情,當(dāng)這段代碼再轉(zhuǎn)給第三個(gè)人時(shí),第三個(gè)人還需要再經(jīng)歷完整的流程,一個(gè)個(gè)函數(shù)、一行行代碼去閱讀,去記憶。
如果你把這個(gè)當(dāng)作是對程序的深入了解程度、對業(yè)務(wù)的嫻熟掌握,那么我覺得我也幫不了你了。
就像是現(xiàn)在超市結(jié)賬時(shí),沒有柜員會以能夠記憶N多商品價(jià)格而感到驕傲,掃碼槍能做到的事情,為什么要占用你的大腦呢。

基礎(chǔ)用法

如上文所說的,JSDoc 是寫在注釋中的一些特定格式內(nèi)容。
在 JavaScript 文件中大部分的標(biāo)記都是塊級形式的,也就是使用 /** XXX */ 來進(jìn)行定義,不過如果你愿意的話,也可以寫到代碼里邊去。

JSDoc 提供了很多種標(biāo)記,用于各種場景。
但并不是所有的都是常用的(而且使用了 vscode 以后,很多需要手動指定的標(biāo)記,編輯器都能夠代替你完成),常用的無外乎以下幾個(gè):

@type 標(biāo)識變量類型

@param 標(biāo)識函數(shù)參數(shù)類型及描述

@return 標(biāo)識函數(shù)返回值類型及描述

完整的列表可以在這里找到 Block tags

基本上使用以上三種標(biāo)記以后,已經(jīng)能夠解決絕大部分的問題。
JSDoc 在寫法上有著特定的要求,比如說行內(nèi)也必須要是這樣的結(jié)構(gòu) /** XXX */,如果是 /* XXX */ 則會被忽略。
而多行的寫法是比較常用的,在 vscode 中可以直接在函數(shù)上方鍵入 /** 然后回車,編輯器會自動填充很多的內(nèi)容,包括參數(shù)類型、參數(shù)描述以及函數(shù)描述的預(yù)留位置,使用TAB鍵即可快速切換。

實(shí)際上@type的使用頻率相較于其他兩個(gè)是很低的,因?yàn)榇蠖鄶?shù)情況下@type用于標(biāo)識變量的類型。
而變量的來源基本上只有兩個(gè) 1. 基本類型賦值 2. 函數(shù)返回值
首先是第一個(gè)基本類型的賦值,這個(gè)基本上 vscode 就幫你做了,而不需要自己手動的去指定。
而另外一個(gè)函數(shù)的返回值,如果我們在函數(shù)上添加了@return后,那么調(diào)用該函數(shù)并獲取返回值的變量類型也會被設(shè)置為@return對應(yīng)的類型。

type
不過因?yàn)槠渌麅蓚€(gè)標(biāo)記中都有類型相關(guān)的指定,所以就拿 @type 來說明一下

首先,在 JSDoc 中是支持所有的基本類型的,包括數(shù)字、字符串、布爾值之類的。

/** @type {number} */
/** @type {string} */
/** @type {boolean} */
/** @type {RegExp} */

// 或者是一個(gè)函數(shù)
/** @type {function} */

// 一個(gè)包含參數(shù)的函數(shù)
/** @type {function(number, string)} */

// Object結(jié)構(gòu)的參數(shù)
/** @type {function({ arg1: number, arg2: string })} */

// 一個(gè)包涵參數(shù)和返回值的函數(shù)
/** @type {function(number, string): boolean} */
在 vscode 中鍵入以上的注釋,都可以很方便的得到動態(tài)提示。  
當(dāng)然了,關(guān)于函數(shù)的,還是推薦使用 @param 和 @return 來實(shí)現(xiàn),效果更好一些
擴(kuò)展復(fù)雜類型

上邊的示例大多是基于基本類型的描述,但實(shí)際開發(fā)過程中不會說只有這么些基本類型供你使用的。
必然會存在著大量的復(fù)雜結(jié)構(gòu)類型的變量、參數(shù)或返回值。

關(guān)于函數(shù)參數(shù),在 JSDoc 中兩種方式可以描述復(fù)雜類型:

不過這個(gè)只能應(yīng)用在@param中,而且復(fù)用性并不高,如果有好幾處同樣結(jié)構(gòu)的定義,那我們就需要把這樣的注釋拷貝多份,顯然不是一個(gè)優(yōu)雅的寫法。
又或者我們可以使用另外兩個(gè)標(biāo)記,@typedef@property,格式都與上邊提到的標(biāo)記類似,可以應(yīng)用在所有需要指定類型的地方:

使用@typedef定義的類型可以很輕松的復(fù)用,在需要的地方直接指定我們定義好的類型即可。
同理,這樣的自定義類型可以直接應(yīng)用在@return中。

param

這個(gè)算是比較重要的一個(gè)標(biāo)記了,用來標(biāo)記函數(shù)參數(shù)的相關(guān)信息。
具體的格式是這樣的(切換到 TypeScript 后一般會移除類型的定義,改用代碼中的類型定義):

/**
 * @param {number} param 描述
 */
function test (param) { }

// 或者可以結(jié)合著 @type 來寫(雖說很少會這么寫)

/**
 * @param param 描述
 */
function test (/** @type number */ param) { }
可選參數(shù)

如果我們想要表示一個(gè)參數(shù)為可選的參數(shù),可以的在參數(shù)名上包一個(gè)[]即可。

/**
 * @param {number} [param] 描述
 */
function test (param) { }

同事在文檔中還提到了關(guān)于默認(rèn)值的寫法,實(shí)際上如果你的可選參數(shù)在參數(shù)位已經(jīng)有了默認(rèn)值的處理,那么就不再需要額外的添加[]來表示了,vscode 會幫助你標(biāo)記。

// 文檔中提到的默認(rèn)值寫法
/**
 * @param {number} [param=123] 描述
 */
function test (param = 123) { }

// 而實(shí)際上使用 vscode 以后就可以簡化為
/**
 * @param param 描述
 */
function test (param = 123) { }

兩者效果是一樣的,并且由于我們手動指定了一個(gè)基礎(chǔ)類型的值,那么我們連類型的指定都可以省去了,簡單的定義一下參數(shù)的描述即可。

return

該標(biāo)記就是用來指定函數(shù)的返回值,用法與@param類型,并且基本上這兩個(gè)都會同時(shí)出現(xiàn),與@param的區(qū)別在于,因?yàn)?b>@return只會有一個(gè),所以不會像前者一樣還需要指定參數(shù)名。

/**
 * @return {number} 描述
 */
function test () { }
Promise 類型的返回值處理

現(xiàn)在這個(gè)年代,基本上Promise已經(jīng)普及開來,所以很多函數(shù)的返回值可能并不是結(jié)果,而是一個(gè)Promise。
所以在vscode中,基于Promise去使用@return,有兩種寫法可以使用:

// 函數(shù)返回 Promise 實(shí)例的情況可以這么指定類型
/**
 * @return {Promise}
 */
function test () {
  return new Promise((res) => {
    res(1)
  })
}

// 或者使用 async 函數(shù)定義的情況下可以省略 @return 的聲明
async function test () {
  return 1
}

  // 如果返回值是一個(gè)其他定義了類型的函數(shù) or 變量,那么效果一樣
async function test () {
  return returnVal()
}

/** @return {string} */
function returnVal () {}
小結(jié)

再回到我們最初的那個(gè)代碼片段上,將其修改為添加了 JSDoc 版本的樣子:

/**
 * @typedef   {Object} UserInfo
 * @property  {number} uid  用戶UID
 * @property  {string} name 昵稱
 * 
 * @typedef   {Object} Order
 * @property  {number} orderId 訂單ID
 * @property  {number} price   訂單價(jià)格
 */
async function main () {
  const uid = 1

  const orders = await createOrder(uid)

  const userInfo = await getUserInfo(uid)

  await notify(userInfo, orders)
}

/**
 * 獲取用戶信息
 * @param   {number} uid 用戶UID
 * @return  {Promise}
 */
async function getUserInfo (uid) { }

/**
 * 創(chuàng)建訂單
 * @param  {number} uid 用戶UID
 * @return {Promise}
 */
async function createOrder (uid) { }

/**
 * 發(fā)送通知
 * @param {UserInfo} userInfo 
 * @param {Order}    orders 
 */
async function notify (userInfo, orders) { }

實(shí)際上并沒有添加幾行文本,在切換到 TypeScript 之前,使用 JSDoc 能夠在一定程度上降低維護(hù)成本,尤其是使用 vscode 以后,要手動編寫的注釋實(shí)際上是沒有多少的。
但是帶來的好處就是,維護(hù)者能夠很清晰的看出函數(shù)的作用,變量的類型。代碼即文檔。
并且在進(jìn)行日常開發(fā)時(shí),結(jié)合編輯器的自動補(bǔ)全、動態(tài)提示功能,想必一定是能夠提高開發(fā)體驗(yàn)的。

上邊介紹的只是 JSDoc 常用的幾個(gè)標(biāo)記,實(shí)際上還有更多的功能沒有提到,具體的文檔地址:jsdoc

參考資料

jsdoc | @return

jsdoc | @param

jsdoc | @typedef

jsdoc | @property

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103756.html

相關(guān)文章

  • Javascript自動化文檔工具:YUI Doc, JSDoc 3, JSDuck等比較

    摘要:本文比較了種較為主流的注釋文檔生成工具。應(yīng)該說是非常適合開源項(xiàng)目多個(gè)作者共同維護(hù)的一個(gè)文檔工具。最后我選擇了作為文檔生成的工具。為了支持多種語言,它僅對注釋塊內(nèi)部的內(nèi)容進(jìn)行解析。 最近隨著寫Node以及獨(dú)立的CommonJS模塊越來越多,我發(fā)現(xiàn)有一份好的文檔不僅可以幫助自己在應(yīng)用這些接口的時(shí)候不至于迷糊,而且對于共同開發(fā)的情況下,能夠省去大量團(tuán)隊(duì)的交流和Debug的時(shí)間。 本文比較了...

    tyheist 評論0 收藏0
  • 代碼注釋藝術(shù),再也不怕被說代碼讀性差啦!

    摘要:優(yōu)秀的代碼注釋可以提高代碼可讀性,當(dāng)然優(yōu)秀的命名規(guī)范也可以啦。表示函數(shù)是異步的。行注釋行注釋的話,應(yīng)該不用做太多的解釋,直接用注釋相關(guān)信息就啦。 showImg(http://ws1.sinaimg.cn/large/005NRne3gy1g34cu772u0j30s00v4wko.jpg); 前言 可能現(xiàn)在不管大家去面試還是在公司上班都會涉及到代碼可讀性,或者是代碼規(guī)范。優(yōu)秀的代碼注...

    zengdongbao 評論0 收藏0
  • 五分鐘玩轉(zhuǎn)文檔化工具JSDuck

    摘要:我們在對現(xiàn)在較主流的五個(gè)文檔工具分別作了調(diào)研和嘗試,得到結(jié)論如下工具優(yōu)點(diǎn)缺點(diǎn)提供了完整的模板開發(fā)事件觸發(fā)等接口,使用非常靈活。至此,的環(huán)境部署已經(jīng)全部完成了。 字?jǐn)?shù):981 閱讀時(shí)間:5分鐘 選型依據(jù) ? 在經(jīng)歷了數(shù)個(gè)上線的項(xiàng)目之后,筆者所在的團(tuán)隊(duì)已經(jīng)沉淀了一個(gè)相對穩(wěn)定版本的前端框架。因此,我們需要出具一套框架API文檔,以便公司其他成員的使用和框架的后期維護(hù)。我們在對...

    rickchen 評論0 收藏0
  • VSCode + JSDoc 完美實(shí)現(xiàn)(almost)JavaScript代碼提示

    摘要:的出現(xiàn)大有統(tǒng)一輕量級領(lǐng)域之勢,在其新版本中自帶了的解析功能,幫助開發(fā)者通過書寫注釋的形式向提供必要信息,完善提示功能。如果因?yàn)檫@種需求就額外的,就會破壞了代碼正常的依賴關(guān)系。 弱類型腳本語言的代碼提示功能一直是開發(fā)者一個(gè)隱隱的痛點(diǎn),沒有它也不是不能干活,但是經(jīng)常因?yàn)槌霈F(xiàn)拼寫錯(cuò)誤或不經(jīng)意的修改導(dǎo)致的變量丟失而耗費(fèi)無畏的時(shí)間在與業(yè)務(wù)邏輯無關(guān)的地方。VSCode的出現(xiàn)大有統(tǒng)一輕量級IDE領(lǐng)域...

    wslongchen 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<