欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript文檔注釋深入講解(非常詳細(xì))

 更新時(shí)間:2024年01月16日 09:43:18   作者:少莫千華  
這篇文章主要給大家介紹了關(guān)于JavaScript文檔注釋的相關(guān)資料,當(dāng)編寫代碼時(shí)文檔注釋是一種特殊的注釋格式,用于描述函數(shù)、類、方法或變量的功能、使用方法和參數(shù)等詳細(xì)信息,需要的朋友可以參考下

什么是文檔注釋

在JavaScript中,文檔注釋是一種特殊的注釋格式,用于描述代碼的功能、使用方法、參數(shù)、返回值等信息。文檔注釋通常使用特定的注釋標(biāo)記和結(jié)構(gòu)來表示,并且可以通過工具解析生成文檔。

在JavaScript中,常用的文檔注釋格式是使用 /** 和 */ 括起來的多行注釋。例如:

/**
 * 這是一個(gè)示例函數(shù),用于加法運(yùn)算。
 * @param {number} a - 第一個(gè)操作數(shù)
 * @param {number} b - 第二個(gè)操作數(shù)
 * @returns {number} - 兩個(gè)操作數(shù)的和
 */
function add(a, b) {
  return a + b;
}

上面的代碼段中,以 /** 開始和以 */ 結(jié)束的多行注釋就是文檔注釋。在注釋的內(nèi)容中,使用了一些特殊的標(biāo)記來表示相關(guān)信息,比如 @param 表示參數(shù),@returns 表示返回值。可以在這些標(biāo)記后面添加具體的描述和類型信息。

為什么要寫文檔注釋

編寫JavaScript的文檔注釋有助于提高代碼的可讀性、生成易于閱讀的API文檔、明確接口規(guī)范、輔助調(diào)試和維護(hù)工作,以及促進(jìn)團(tuán)隊(duì)合作和知識共享。這是為了更好地組織和記錄代碼,并使其更易于理解和使用的最佳實(shí)踐之一。

  • 提供代碼的可讀性:文檔注釋可以幫助其他開發(fā)人員更好地理解你的代碼。通過提供清晰的注釋,可以解釋代碼的目的、使用方法和重要細(xì)節(jié),使代碼更易于閱讀和維護(hù)。
  • 自動(dòng)生成文檔:許多開發(fā)工具和框架可以根據(jù)代碼中的文檔注釋來自動(dòng)生成文檔。例如,JSDoc 是一個(gè)常用的JavaScript文檔生成工具,它可以解析文檔注釋并生成API文檔。這樣其他開發(fā)人員就可以輕松地查看代碼的接口和用法。
  • 提供接口定義和規(guī)范:通過文檔注釋,可以明確說明函數(shù)、類、方法和參數(shù)的用途、類型和預(yù)期行為。這不僅幫助其他開發(fā)人員正確使用你的代碼,還可以在團(tuán)隊(duì)協(xié)作中提供一致性和規(guī)范。
  • 輔助代碼調(diào)試和維護(hù):當(dāng)你在調(diào)試和維護(hù)代碼時(shí),文檔注釋可以提供有關(guān)代碼功能和實(shí)現(xiàn)細(xì)節(jié)的重要信息。這對于理解復(fù)雜的功能和排查問題非常有幫助,尤其是當(dāng)你需要處理他人編寫的代碼或長時(shí)間未接觸的代碼時(shí)。
  • 促進(jìn)團(tuán)隊(duì)合作和知識共享:文檔注釋可以為開發(fā)團(tuán)隊(duì)提供一個(gè)共享的知識庫,使所有人都能理解代碼的功能和實(shí)現(xiàn)細(xì)節(jié)。這有助于提高團(tuán)隊(duì)成員之間的溝通和協(xié)作,并促進(jìn)代碼質(zhì)量和一致性。

//行注釋對于編輯器來說是無效的注釋,雖然func從名字上看上去應(yīng)該是一個(gè)方法,但是編輯器(vscode)不知道它是一個(gè)函數(shù)

// 函數(shù)防抖
function debounce(func,duration = 1000) {
  
}

當(dāng)鼠標(biāo)放到函數(shù)上時(shí),編輯器并不知道這個(gè)函數(shù)的功能是“函數(shù)防抖”

當(dāng)鼠標(biāo)放到參數(shù)func上時(shí),編輯器并不知道這個(gè)參數(shù)是函數(shù)

不使用文檔注釋存在的隱患

使用函數(shù)成員時(shí)的書寫問題

在使用函數(shù)成員時(shí),能有效的降低書寫錯(cuò)誤。因此,你在使用函數(shù)里面的一些成員的時(shí)候

// 函數(shù)防抖
function debounce(func,duration = 1000) {
  func.aply
}

如:當(dāng)你在debounce函數(shù)內(nèi)部使用func.apply,它沒有智能提示,因?yàn)樗恢?code>apply是一個(gè)函數(shù)

那你稍微不注意把單詞寫錯(cuò)成aply,就增加了出錯(cuò)的幾率啊。

在開發(fā)過程中,有相當(dāng)一部分程序問題就是由于單詞拼寫錯(cuò)誤導(dǎo)致的。

有人又說了有AI智能提示不是比文檔注釋更好用嗎?

雖然TypeScript(AI自動(dòng)補(bǔ)全)就是來解決這個(gè)單詞書寫錯(cuò)誤的問題的,畢竟很多項(xiàng)目里面沒有上TypeScript (AI自動(dòng)補(bǔ)全)。這工具也不是你想用就能用的,他涉及到隱私、費(fèi)用、不支持等等原因。所以TypeScript只能起到錦上添花的作用。

調(diào)用函數(shù)時(shí)功能使用問題

// 函數(shù)防抖
function debounce(func,duration = 1000) {
}

debounce

debounce函數(shù)使用的時(shí)候我們能從這個(gè)單詞的含義知道,它是一個(gè)防抖函數(shù),如果我們把這個(gè)函數(shù)的名稱改成wefwfas,我們不知道他的作用是什么,使用的時(shí)候沒有任何提示,只知道要傳2個(gè)參數(shù),至于參數(shù)的含義、類型等等都不知道。因此我們最好是寫文檔注釋。

// 函數(shù)防抖
function wefwfas(func,duration = 1000) {
}

wefwfas

/**
 * 
 * @param {*} func 
 * @param {*} duration 
 */
function wefwfas(func,duration = 1000) {
  
}

文檔注釋

官方標(biāo)簽

函數(shù)

如下我們可以給函數(shù)寫一個(gè)注釋函數(shù)防抖:

/**
 * 函數(shù)防抖
 * @param {*} func 
 * @param {*} duration 
 */
function debounce(func,duration = 1000) {

}

debounce()

當(dāng)鼠標(biāo)放到函數(shù)上時(shí),它就會(huì)提示這個(gè)函數(shù)的名字是函數(shù)防抖

當(dāng)我們使用的時(shí)候,同樣的可以看到它是函數(shù)防抖的函數(shù)

由于平時(shí)封裝的函數(shù)日積月累,如果不添加文檔注釋的話,很多函數(shù)都忘記其作用了。

參數(shù)標(biāo)簽 @param

參數(shù)類型 {}

針對函數(shù)每一個(gè)參數(shù)也可以添加文檔注釋,其中以關(guān)鍵字param(parameter) 開始,格式如下:

  * @param {<type>} <param-name> <comments>
  •  param: 參數(shù)關(guān)鍵字
  •  <type>: 參數(shù)類型,
    • * - 支持接收所有類型
    • Number - 只接收一種
    • Function|Number - 兼容多種
  •  <param-name>: 名稱
  •  <comments>: 參數(shù)說明

如下所示:

  • 參數(shù)func 類型是Function
  • 參數(shù)duration類型是Number
/**
 * 函數(shù)防抖
 * @param {Function} func 
 * @param {Number} duration 
 */
function debounce(func,duration = 1000) {

}

debounce()

當(dāng)我們把鼠標(biāo)放到這個(gè)參數(shù)上時(shí),編輯器就知道

func是函數(shù)。

/**
 * 函數(shù)防抖
 * @param {Function} func 
 * @param {Number} duration 
 */
function debounce(func,duration = 1000) {
  func.call
}

debounce()

所以在實(shí)現(xiàn)這個(gè)函數(shù)的時(shí)候,當(dāng)我們使用func.applyfunc.call這些函數(shù)方法的時(shí)候都有提示了。

當(dāng)我們需要調(diào)用這個(gè)函數(shù)時(shí),鼠標(biāo)放到調(diào)用的函數(shù)上的時(shí)候,編輯器就會(huì)告訴我這個(gè)參數(shù)是一個(gè)函數(shù)。

參數(shù)注釋

可以給這個(gè)參數(shù)呢加上注釋,如下示例

/**
 * 函數(shù)防抖
 * @param {Function} func 防抖的目標(biāo)函數(shù)
 * @param {Number} duration 函數(shù)執(zhí)行前等待的時(shí)間
 */
function debounce(func,duration = 1000) {

}

debounce()

現(xiàn)在我們再用鼠標(biāo)放到參數(shù)上看看編輯器會(huì)怎么提示我們:

對象屬性屬性注釋

如果參數(shù)是object我們還可以對object的每個(gè)屬性單獨(dú)添加注釋
``

/**
 * 網(wǎng)絡(luò)請求
 * @param {object} options 配置對象
 * @param {string} options.url 請求地址
 * @param {'GET'|'POST'} options.method 請求方法
 * @param {object} options.body  
 * @param {object} options.headers  
 */
async function request(options) { }
  • url - 是字符串
  • method - 是字符串選項(xiàng),可以是GET也可以是POST
  • body - 是對象
  • headers - 是對象

使用帶有對象屬性注釋的參數(shù)

/**
 * 網(wǎng)絡(luò)請求
 * @param {object} options 配置對象
 * @param {string} options.url 請求地址
 * @param {'GET'|'POST'} options.method 請求方法
 * @param {object} options.body  
 * @param {object} options.headers  
 */
async function request(options) { }

request()

我們看看編輯器會(huì)怎么提示我們:

返回值標(biāo)簽 @returns

針對有返回值函數(shù)可以添加返回值的注釋,其中以關(guān)鍵字returns開始,格式如下:

  * @returns {<type>} <comments>
  •  returns: 返回值關(guān)鍵字
  •  <type>: 參數(shù)類型,
    • * - 支持接收所有類型
    • Number - 只接收一種
    • Function|Number - 兼容多種
  •  <comments>: 參數(shù)說明
/**
 * 函數(shù)防抖
 * @param {Function} func 防抖的目標(biāo)函數(shù)
 * @param {Number} duration 函數(shù)執(zhí)行前等待的時(shí)間
 * @returns {Function} 返回一個(gè)防抖的函數(shù)
 */
function debounce(func,duration = 1000) {

}

debounce()

這樣返回值的類型也確定下來了,我們看看編輯器是怎么提示我們的:

作者標(biāo)簽 @author

可以添加作者有關(guān)的注釋,其中以關(guān)鍵字author開始,格式如下:

  * @author <author-name> <contact-way>
  •  author: 作者信息關(guān)鍵字
  •  <author-name>: 作者姓名
  •  <contact-way>: 聯(lián)系方式,可以是個(gè)人網(wǎng)頁、郵箱等等。例如:<370763160@qq.com>
/**
 * 函數(shù)防抖
 * @author ISail <370763160@qq.com>
 * @param {Function} func 防抖的目標(biāo)函數(shù)
 * @param {Number} duration 函數(shù)執(zhí)行前等待的時(shí)間
 * @returns {Function} 返回一個(gè)防抖的函數(shù)
 */
function debounce(func,duration = 1000) {

}

debounce()

我們看看編輯器會(huì)怎么提示我們,點(diǎn)擊<370763160@qq.com>還可以發(fā)郵件。

請?zhí)砑訄D片描述

許可證標(biāo)簽 @license

可以添加版權(quán)有關(guān)的注釋,其中以關(guān)鍵字license開始,格式如下:

  * @license <license-info>
  •  license: 版權(quán)信息關(guān)鍵字
  •  <license-info>: 指定代碼的許可證信息??梢燥@示多行

在使用 @license 標(biāo)簽時(shí),開發(fā)者應(yīng)該根據(jù)代碼的實(shí)際許可情況填寫適當(dāng)?shù)脑S可證信息。這有助于提供清晰的許可證聲明,保護(hù)代碼的知識產(chǎn)權(quán),并促進(jìn)合規(guī)和合理的代碼使用。

許可證分類

1. 開源許可證(Open Source Licenses)

這些許可證基于開源原則,允許使用、修改和分發(fā)源代碼或衍生作品。常見的開源許可證包括MIT許可證、BSD許可證、Apache許可證等。

下面是各種常見許可證之間的差異的詳細(xì)比較表格

許可證類型商業(yè)使用分發(fā)修改源代碼發(fā)布聲明更改分發(fā)條件專利許可網(wǎng)絡(luò)服務(wù)使用許可證嵌入
GPL強(qiáng)保護(hù)Copyleft
LGPL弱保護(hù)可選空白條件
AGPL強(qiáng)保護(hù)空白條件
New BSD自由空白條件
Simple BSD自由空白條件
MIT自由空白條件
Apache自由空白條件
Apache 2.0自由空白條件
MPL弱保護(hù)空白條件
Mozilla MPL 2弱保護(hù)空白條件
CDDL弱保護(hù)空白條件
CPL弱保護(hù)空白條件
EPL弱保護(hù)空白條件
CC弱保護(hù)空白條件
CC0自由空白條件
WTFPL自由空白條件

下面是各列的解釋:

  • 類型:許可證類型,分類為 “強(qiáng)保護(hù)”(對派生作品有限制)和 “弱保護(hù)”(提供更大的自由度)。
  • 商業(yè)使用:許可證是否允許商業(yè)使用。
  • 分發(fā)修改:許可證是否允許分發(fā)修改后的代碼。
  • 源代碼發(fā)布:許可證是否要求源代碼的公開發(fā)布。
  • 聲明更改:許可證是否要求在修改后的代碼中聲明更改。
  • 分發(fā)條件:許可證對分發(fā)軟件的條件要求。
  • 專利許可:許可證是否授予使用專利的權(quán)利。
  • 網(wǎng)絡(luò)服務(wù)使用:許可證是否允許使用者基于該軟件提供網(wǎng)絡(luò)服務(wù)。
  • 許可證嵌入:許可證是否要求在使用軟件的產(chǎn)品中嵌入許可證信息。
    請注意,這個(gè)表格只提供了對常見許可證之間的主要差異的概述。具體的許可證條款和條件應(yīng)該參考每個(gè)許可證的官方文檔和相關(guān)說明。選擇適當(dāng)?shù)脑S可證需要根據(jù)項(xiàng)目需求和法律咨詢進(jìn)行綜合考慮。另外,這里列出的是一些常見的開源許可證,而還有其他類型的許可證可供選擇。

2. 版權(quán)聲明(Copyright Declaration)

這種分類主要用于聲明代碼的版權(quán)歸屬,指明作者或組織對代碼的所有權(quán)。在這種情況下,@license 標(biāo)簽通常包含版權(quán)聲明和版權(quán)所有者的信息。

/**
 * @license
 * 
 * 項(xiàng)目一 版本1.0.0
 * (c) 2023年 ISail
 * 根據(jù)“項(xiàng)目一許可證”發(fā)布。
 * 
 * https://www.example.com/licenses/myproject-license
 */

在這個(gè)例子中,我們假設(shè)一個(gè)名為 “項(xiàng)目一” 的項(xiàng)目,作者為 ISail。他在注釋中使用 @license 標(biāo)簽來聲明版權(quán)信息。下面是每個(gè)部分的解釋:

  • 項(xiàng)目一 版本1.0.0:指定了項(xiàng)目的版本號。
  • (c) 2023年 ISail:聲明了版權(quán)歸屬于 ISail,即聲明了版權(quán)歸屬于,又指明了版權(quán)年份。
  • 根據(jù)“項(xiàng)目一”許可證發(fā)布。:說明代碼是根據(jù) “項(xiàng)目一許可證” 發(fā)布的。
  • https://www.example.com/licenses/project1-license:提供了一個(gè)鏈接,指向一個(gè)包含詳細(xì)許可證條款的網(wǎng)頁。

3. 私有許可證(Proprietary Licenses)

私有許可證用于保護(hù)代碼的知識產(chǎn)權(quán),限制未經(jīng)許可的使用和分發(fā)。在這種情況下,@license 標(biāo)簽可能包含具體的許可條款和使用限制,以及聯(lián)系方式以獲取許可。

/**
 * @license
 * 
 * 庫一 版本2.0.0
 * (c) 2023年 少莫千華無限公司。 保留所有權(quán)利。
 * 
 * 這是一款私有軟件。嚴(yán)禁未經(jīng)授權(quán)擅自復(fù)制或傳播本軟件或其任何部分。
 * 
 * 如需咨詢許可證相關(guān)信息, 請聯(lián)系:
 * 370763160@qq.com
 */

在這個(gè)例子中,我們假設(shè)一個(gè)名為 “庫一” 的庫,歸屬于 少莫千華無限公司。。作者明確聲明了版權(quán)信息,并添加了與私有許可證相關(guān)的說明。下面是每個(gè)部分的解釋:

  • 庫一 版本2.0.0:指定了庫的版本號。
  • (c) 2023年 少莫千華無限公司。 保留所有權(quán)利。:聲明了版權(quán)歸屬于少莫千華無限公司。,并表示保留所有權(quán)利。
  • 這是一款私有軟件。嚴(yán)禁未經(jīng)授權(quán)擅自復(fù)制或傳播本軟件或其任何部分。:明確說明這是一款私有軟件,未經(jīng)許可嚴(yán)禁復(fù)制或分發(fā)軟件或其任何部分。
  • 如需咨詢許可證相關(guān)信息, 請聯(lián)系:370763160@qq.com:提供了一個(gè)聯(lián)系方式,以便進(jìn)行許可證相關(guān)的咨詢。

4. 其他許可證(Other Licenses)

這個(gè)分類用于指定其他不屬于常見類別的特定許可證。

/**
 * @license
 * 
 * 項(xiàng)目一 版本1.0.0
 * (c) 2023年 ISail
 * 根據(jù)Apache許可證2.0發(fā)布
 * 
 * SPDX-License-Identifier: Apache-2.0
 * 
 * 了解更多信息,請?jiān)L問:
 * https://www.apache.org/licenses/LICENSE-2.0
 */

在這個(gè)例子中,我們假設(shè)一個(gè)名為 “項(xiàng)目一” 的項(xiàng)目,作者為 ISail。他在注釋中使用 @license 標(biāo)簽來聲明版權(quán)信息,并指定了使用的許可證。下面是每個(gè)部分的解釋:

  • 項(xiàng)目一 版本1.0.0:指定了項(xiàng)目的版本號。
  • (c) 2023年 ISail:聲明了版權(quán)歸屬于 ISail,并指明了版權(quán)年份。
  • 根據(jù)Apache許可證2.0發(fā)布:說明代碼是根據(jù) Apache License 2.0 發(fā)布的。
  • SPDX-License-Identifier: Apache-2.0使用 SPDX許可證標(biāo)識符明確指定了所采用的許可證。
  • https://www.apache.org/licenses/LICENSE-2.0:提供了一個(gè)鏈接,指向一個(gè)包含詳細(xì)許可證條款的網(wǎng)頁。
/**
 * 函數(shù)防抖
 * @author ISail <370763160@qq.com>
 * @license MIT
 * @param {Function} func 防抖的目標(biāo)函數(shù)
 * @param {Number} duration 函數(shù)執(zhí)行前等待的時(shí)間
 * @returns {Function} 返回一個(gè)防抖的函數(shù)
 */
function debounce(func,duration = 1000) {

}

debounce()

示例標(biāo)簽 @example

可以在注釋中添加示例,提示如何使用這個(gè)函數(shù),其中以關(guān)鍵字example開始,格式如下:

/**
 * 獲取指定范圍內(nèi)的隨機(jī)整數(shù)
 * @param {number} min 隨機(jī)數(shù)的最小值
 * @param {number} max 隨機(jī)數(shù)的最大值
 * @return {number} 隨機(jī)數(shù) 
 * @example
 * getRange(1, 10); // 獲取[1,10]之間的隨機(jī)數(shù)
 */
function getRandom(min, max) { }

getRandom

我們看看編輯器會(huì)怎么提示我們:

定義對象標(biāo)簽 @typedef 和屬性標(biāo)簽 @property

在下面的例子中,使用@typedef關(guān)鍵字定義了一個(gè)名為User的類型別名,并使用@property關(guān)鍵字指定了User對象的各個(gè)屬性及其類型。接下來,getUserInfo函數(shù)使用@param關(guān)鍵字指定了參數(shù)userId的類型為number,并使用@returns關(guān)鍵字指定了返回值類型為User`對象。

通過使用@typedef關(guān)鍵字,我們可以在文檔注釋中清晰地指定變量、屬性和函數(shù)的類型,提高代碼可讀性和可維護(hù)性。

/**
 * 用戶對象
 * @typedef {object} User
 * @property {number} id - 用戶ID
 * @property {string} name - 用戶名
 * @property {string} email - 用戶電子郵箱
 * @property {Date} birthday - 用戶生日
 */

/**
 * 獲取用戶信息
 * @param {number} userId - 用戶ID
 * @returns {User} - 返回用戶對象
 */
function getUserInfo(userId) {
  // ...
}

const user = getUserInfo(123);
console.log(user.name); // 輸出用戶的用戶名

我們看看編輯器會(huì)怎么提示我們:

異常標(biāo)簽 @throws

在下面的例子中,divide函數(shù)使用@param關(guān)鍵字指定了兩個(gè)參數(shù)的類型為number,使用@returns關(guān)鍵字指定了返回值類型為number,并使用@throws關(guān)鍵字指定了可能拋出的異常類型為Error。在函數(shù)內(nèi)部,通過判斷除數(shù)是否為0,如果是則拋出一個(gè)錯(cuò)誤。

通過使用@throws關(guān)鍵字,我們可以提示其他開發(fā)者該函數(shù)可能拋出的異常,使其在調(diào)用函數(shù)時(shí)能夠更好地處理異常情況。而在調(diào)用函數(shù)處,可以使用try...catch語句捕獲并處理異常,避免程序崩潰。

/**
 * 執(zhí)行除法運(yùn)算
 * @param {number} dividend - 被除數(shù)
 * @param {number} divisor - 除數(shù)
 * @returns {number} - 返回除法結(jié)果
 * @throws {Error} 如果除數(shù)為0,則拋出錯(cuò)誤
 */
function divide(dividend, divisor) {
  if (divisor === 0) {
    throw new Error("除數(shù)不能為0");
  }
  return dividend / divisor;
}

try {
  const result = divide(10, 0);
  console.log(result);
} catch (error) {
  console.error(error.message);
}

我們看看編輯器會(huì)怎么提示我們:

廢棄標(biāo)簽 @deprecated

在下面的例子中,通過使用@deprecated關(guān)鍵字,我們將原來的add函數(shù)標(biāo)記為已廢棄,并在注釋中說明了該函數(shù)已被廢棄,建議使用新的addNumbers函數(shù)代替。在代碼中,我們首先調(diào)用了已廢棄的add函數(shù)來計(jì)算兩個(gè)數(shù)字的和,然后使用新的addNumbers函數(shù)來計(jì)算多個(gè)數(shù)字的和。

/**
 * @deprecated 該函數(shù)已被廢棄,請使用新的 addNumbers 函數(shù)代替。
 * 將兩個(gè)數(shù)字相加
 * @param {number} a - 第一個(gè)數(shù)字
 * @param {number} b - 第二個(gè)數(shù)字
 * @returns {number} - 返回相加的結(jié)果
 */
function add(a, b) {
  return a + b;
}

/**
 * 將多個(gè)數(shù)字相加
 * @param {...number} numbers - 要相加的數(shù)字列表
 * @returns {number} - 返回相加的結(jié)果
 */
function addNumbers(...numbers) {
  return numbers.reduce((sum, number) => sum + number, 0);
}

console.log(add(2, 3)); // 輸出: 5

console.log(addNumbers(2, 3, 4)); // 輸出: 9

我們看看編輯器會(huì)怎么提示我們:

約定標(biāo)簽

成員的可見性 @private @protected @public

  • _xxxx - 私有成員
  • @private - 私有成員
  • @protected - 保護(hù)成員
  • @public- 公共成員
    在下面的例子中,我們使用了下劃線 _ 來約定將屬性標(biāo)記為私有,以表示該屬性應(yīng)該被視為私有成員。在構(gòu)造函數(shù)中,我們使用注釋@private來說明該屬性是私有的。而在getName方法中,我們并沒有使用注釋@private,因?yàn)樵摲椒ㄊ枪驳?,可以由外部訪問。
/**
 * 創(chuàng)建一個(gè)動(dòng)物類
 * @class
 */
class Animal {
  /**
   * 構(gòu)造函數(shù)
   * @param {string} name - 名稱
   * @private
   */
  constructor(name) {
    this.name = name; // 公共屬性
    this._age = 0; // 私有屬性,約定以 "_" 開頭
    this._weight = 0; // 私有屬性,約定以 "_" 開頭
  }

  /**
   * 公共方法 - 獲取名稱
   * @returns {string} - 返回名稱
   * @public
   */
  getName() {
    return this.name;
  }

  /**
   * 保護(hù)方法 - 獲取年齡
   * @returns {number} - 返回年齡
   * @protected
   */
  _getAge() {
    return this._age;
  }
}

/**
 * 創(chuàng)建一個(gè)狗類,繼承自動(dòng)物類
 * @class
 */
class Dog extends Animal {
  /**
   * 構(gòu)造函數(shù)
   * @param {string} name - 名稱
   */
  constructor(name) {
    super(name);
    this.breed = "unknown"; // 公共屬性
  }

  /**
   * 公共方法 - 獲取品種
   * @returns {string} - 返回品種
   * @public
   */
  getBreed() {
    return this.breed;
  }

  /**
   * 公共方法 - 獲取年齡和名稱
   * @returns {string} - 返回年齡和名稱的字符串
   * @public
   */
  getAgeAndName() {
    const age = this._getAge(); // 子類可以訪問父類的保護(hù)方法
    return `Age: ${age}, Name: ${this.name}`;
  }
}

const animal = new Animal("Animal");
console.log(animal.name); // 可以直接訪問公共屬性 "name"
console.log(animal._age); // 仍然可以直接訪問約定為私有的屬性 "_age"

const dog = new Dog("Dog");
console.log(dog.name); // 可以直接訪問公共屬性 "name"
console.log(dog.breed); // 可以直接訪問公共屬性 "breed"
console.log(dog._getAge()); // 子類可以調(diào)用父類的保護(hù)方法 "_getAge"
console.log(dog._age); // 仍然可以直接訪問約定為私有的屬性 "_age"
console.log(dog.getAgeAndName()); // "Age: 0, Name: Dog"

在上面的例子中,我們使用了命名約定和注釋來模擬 @private@public、@protected 關(guān)鍵字。約定是使用 _ 開頭將屬性標(biāo)記為私有,不使用任何特殊約定將屬性標(biāo)記為公共的。

  • name 屬性在 Animal 類中是公共的,可以通過對象實(shí)例直接訪問。
  • _age 屬性和 _getAge 方法在 Animal 類中被約定為私有的,但是在 Dog 類中仍然可以直接訪問。
  • breed 屬性和 getBreed 方法在 Dog 類中是公共的,可以通過對象實(shí)例直接訪問。
  • getAgeAndName 方法在 Dog 類中訪問了父類Animal 的 _getAge 方法。

請注意,這些約定只是一種標(biāo)準(zhǔn)做法,實(shí)際上并不能真正實(shí)現(xiàn)屬性或方法的私有性或保護(hù)性。開發(fā)者仍然可以繞過約定直接訪問被標(biāo)記為私有的屬性。然而,通過使用約定和注釋,我們可以向其他開發(fā)者傳達(dá)哪些成員應(yīng)該被視為私有或保護(hù),以遵循封裝的原則。

類 @class 的繼承 @extends 與方法的重寫 @inheritdoc

/**
 * 車輛類
 * @class
 */
class Vehicle {
  /**
   * 構(gòu)造函數(shù)
   * @param {string} brand - 品牌
   */
  constructor(brand) {
    this.brand = brand; // 公共屬性
  }

  /**
   * 獲取品牌信息
   * @returns {string} - 返回品牌信息
   */
  getBrand() {
    return this.brand;
  }
}

/**
 * 汽車類,繼承自車輛類
 * @class
 * @extends Vehicle
 */
class Car extends Vehicle {
  /**
   * 構(gòu)造函數(shù)
   * @param {string} brand - 品牌
   * @param {string} model - 型號
   */
  constructor(brand, model) {
    super(brand);
    this.model = model; // 公共屬性
  }

  /**
   * @inheritdoc
   */
  getBrand() {
    return super.getBrand();
  }

  /**
   * 獲取車輛信息,包括品牌和型號
   * @returns {string} - 返回車輛信息
   */
  getVehicleInfo() {
    const brand = this.getBrand(); // 調(diào)用父類的方法
    return `Brand: ${brand}, Model: ${this.model}`;
  }
}

const car = new Car("Toyota", "Camry");
console.log(car.getVehicleInfo()); // "Brand: Toyota, Model: Camry"

在上面的例子中,我們使用了 @extends 標(biāo)簽來說明 Car 類繼承自 Vehicle 類。然后,在 getBrand 方法的文檔注釋中使用了 @inheritdoc 標(biāo)簽來表示該方法繼承并重寫了父類的方法。

請注意,這里的 @inheritdoc 標(biāo)簽只是一種約定,并不是 JavaScript 文檔注釋的官方標(biāo)簽。不同的文檔生成工具可能會(huì)對此標(biāo)簽有不同的處理方式。因此,在實(shí)際開發(fā)中,你需要根據(jù)你所使用的文檔生成工具的要求來使用適當(dāng)?shù)臉?biāo)簽或約定。

類型 @type 與只讀 @readonly

/**
 * 用戶類
 * @class
 */
class User {
  /**
   * 創(chuàng)建一個(gè)用戶實(shí)例
   * @param {string} name - 名稱
   */
  constructor(name) {
    /**
     * 用戶名稱
     * @type {string}
     */
    this.name = name;

    /**
     * 用戶ID,只讀屬性
     * @type {number}
     * @readonly
     */
    this.id = generateUniqueId();
  }
}

const user = new User("Alice");
console.log(user.name); // "Alice"
console.log(user.id); // 使用只讀屬性,例如:"123456"

user.name = "Bob"; // 可以修改可寫屬性
user.id = 789; // 嘗試修改只讀屬性,會(huì)導(dǎo)致錯(cuò)誤

在上述示例中,@readonly 標(biāo)簽用于描述 User 類中的 id 屬性。這告訴開發(fā)人員該屬性是只讀的,不能在實(shí)例創(chuàng)建后進(jìn)行修改。這樣,開發(fā)人員在使用該類時(shí)就會(huì)知道如何正確操作屬性。

請注意,JSDoc 標(biāo)簽是一種約定,不同的工具可能會(huì)在生成文檔時(shí)以不同的方式處理標(biāo)簽。但是,@readonly 是在 JSDoc 規(guī)范中定義的標(biāo)準(zhǔn)標(biāo)簽之一,并且受到廣泛支持。因此,它被認(rèn)為是官方標(biāo)簽。

類 @class 與構(gòu)造函數(shù) @constructor

/**
 * 表示一個(gè)人的類
 * @class
 */
class Person {
  /**
   * 創(chuàng)建一個(gè)人的實(shí)例
   * @constructor
   * @param {string} name - 名字
   * @param {number} age - 年齡
   */
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

// 創(chuàng)建一個(gè)人的實(shí)例
const person = new Person("Alice", 25);
console.log(person.name); // "Alice"
console.log(person.age); // 25

在上述示例中,@class 標(biāo)簽用于描述 Person 類,它表示一個(gè)人的類。類的構(gòu)造函數(shù)使用 @constructor 標(biāo)簽進(jìn)行注釋,以指示這是一個(gè)構(gòu)造函數(shù)。

構(gòu)造函數(shù)的文檔注釋使用 @param 標(biāo)簽描述參數(shù),name 參數(shù)表示名字,age 參數(shù)表示年齡。這樣,在使用該類時(shí),開發(fā)人員可以通過文檔了解到構(gòu)造函數(shù)所需的參數(shù)和其作用。

通過使用 @class@constructor 標(biāo)簽,可以為 JavaScript 類提供清晰的文檔注釋,使其他開發(fā)人員能夠更好地理解和使用該類。

自定義標(biāo)簽

請注意,JSDoc 并不對自定義標(biāo)簽提供原生的支持,所以某些工具可能會(huì)忽略或不同程度地支持這些標(biāo)簽。但是,通過約定和規(guī)范,您可以為您的代碼庫添加自定義信息,以便更好地記錄代碼的演化歷史。

歷史記錄@history

/**
 * 計(jì)算兩個(gè)數(shù)字的和
 * @param {number} a - 第一個(gè)數(shù)字
 * @param {number} b - 第二個(gè)數(shù)字
 * @returns {number} 兩個(gè)數(shù)字的和
 * @history
 * - 2021-01-01  初始版本
 * - 2022-05-15  修復(fù) bug:處理負(fù)數(shù)的情況
 */
function addNumbers(a, b) {
  return a + b;
}

在上述示例中,自定義的 @history 標(biāo)簽被用來記錄代碼的發(fā)展歷程。每一行記錄都包含日期和相應(yīng)的注釋。

使用這種方式,您可以在 JSDoc 注釋中記錄多個(gè)版本、修復(fù)或改進(jìn)的歷史信息。這樣,其他開發(fā)人員在查看文檔時(shí)可以了解到代碼的進(jìn)展和變化。

日期@history

/**
 * 計(jì)算兩個(gè)數(shù)字的和
 * @param {number} a - 第一個(gè)數(shù)字
 * @param {number} b - 第二個(gè)數(shù)字
 * @returns {number} 兩個(gè)數(shù)字的和
 * @date 2021-01-01 初始版本
 * @date 2022-05-15 修復(fù) bug:處理負(fù)數(shù)的情況
 */
function addNumbers(a, b) {
  return a + b;
}

在上述示例中,我們使用自定義的 @date 標(biāo)簽來記錄代碼的日期信息。每個(gè)標(biāo)簽都包含日期和相應(yīng)的注釋。

使用這種方式,您可以在 JSDoc 注釋中記錄特定代碼片段的創(chuàng)建日期、修改日期或其他相關(guān)日期。這樣,其他開發(fā)人員在查看文檔時(shí)可以獲得更多的上下文信息。

生成文檔

我們可以把這個(gè)文檔注釋,生成一個(gè)可讀的接口文檔

demo1.js

/**
 * 函數(shù)防抖
 * @author ISail <370763160@qq.com>
 * @license MIT
 * @param {Function} func 防抖的目標(biāo)函數(shù)
 * @param {Number} duration 函數(shù)執(zhí)行前等待的時(shí)間
 * @returns {Function} 返回一個(gè)防抖的函數(shù)
 */
function debounce(func,duration = 1000) { }

demo2.js

/**
 * 獲取指定范圍內(nèi)的隨機(jī)整數(shù)
 * @param {number} min 隨機(jī)數(shù)的最小值
 * @param {aa} max 隨機(jī)數(shù)的最大值
 * @return {aaa} 隨機(jī)數(shù) 
 * @example
 * getRange(1, 10); // 獲取[1,10]之間的隨機(jī)數(shù)
 */
function getRandom(min, max) { }

demo3.js

/**
 * 網(wǎng)絡(luò)請求
 * @param {object} options 配置對象
 * @param {string} options.url 請求地址
 * @param {'GET'|'POST'} options.method 請求方法
 * @param {object} options.body  
 * @param {object} options.headers  
 */
async function request(options) { }

1. 安裝js文檔生成工具

全局安裝jsdoc Document

npm i -g jsdoc

2. 使用js文檔生成工具生成文檔

你就可以使用這個(gè)jsdoc這個(gè)命令了

jsdoc <path>
  • - 文件路徑

點(diǎn)斜桿./表示當(dāng)前目錄的所有文件,下面以生成文檔的示例。

jsdoc ./

3. 查看生成的效果

首頁

debounce 函數(shù)

getRandom 函數(shù)

request 函數(shù)

總結(jié) 

到此這篇關(guān)于JavaScript文檔注釋深入講解的文章就介紹到這了,更多相關(guān)JS文檔注釋內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論