弱類型腳本語言的代碼提示功能一直是開發者一個隱隱的痛點,沒有它也不是不能幹活,可是常常由於出現拼寫錯誤或不經意的修改致使的變量丟失而耗費無畏的時間在與業務邏輯無關的地方。VSCode的出現大有統一輕量級IDE領域之勢,在其新版本中自帶了JSDoc的解析功能,幫助JavaScript開發者經過書寫註釋的形式向IDE提供必要信息,完善提示功能。javascript
先來看一個簡單的例子(微信小程序前端代碼)css
export class CommonUtilsWX { request(o, callback){ //TODO:xxxxx } }
能夠看出該函數的定義中有一個object類型的參數o和一個函數型的回調參數callback。可是單純從代碼定義中IDE沒法得知對象o中必須包含那些字段、callback回調函數中會帶回哪些參數。對於JavaScript等弱類型腳本語言來講不到運行時階段這些信息是沒有意義的,而對於開發者而言,這些信息在一段時間之後很容易遺忘,更別說交付給第三方使用。因此這些信息就須要用JSDoc來書寫出來。前端
export class CommonUtilsWX { /** * 發送網絡請求,通訊協議必須是http或https,數據協議必須是json * @param {object} o 請求參數對象 * @param {string} o.host 請求url的域名,如http://xxx.xxx.com * @param {string} o.path 請求url的路徑,如xxx/xxx * @param {object} o.query 請求url的查詢段,根據對象中key,value拼成key1=value1&key2=value2的形式 * @param {string} o.method 請求方法,如GET,POST等 * @param {object} o.body 請求數據體,僅在method爲POST時有效 * @param {function(Error):void} callback 請求回調,請求成功時error爲空 */ request(o, callback){ //TODO:xxxxx } }
能夠看出JSDoc將參數o的類型和其必要的內部構造,函數類型的參數callback將會帶回的參數類型Error和返回值類型void,等信息都被清晰明確的標記出來,同時附帶了文字註釋。java
此時,直接使用new CommonUtilsWX()
構造出來的對象調用request()
方法能夠看到以下的提示畫面git
而後再向request()
函數傳入字面量對象時,會看到以下的提示畫面github
下面是第二個例子,定義一個對象,並給對象中的字段賦予JSDoc類型信息json
let zy = { /** * sdk版本號 * @type {number} */ version : 0.1, /** * 分享功能管理 * @type {Share|ShareWX} */ share: Share.createAdapter(), /** * 通用工具集,如網絡請求,彈框顯示等 * @type {CommonUtils} */ commonUtils : CommonUtils.createAdapter(), /** * 平臺功能管理,如登陸,用戶信息等 * @type {Platform|PlatformWX} */ platform : Platform.createAdapter(), /** * 排行榜功能管理 * @type {Leaderboard} */ leaderboard : Leaderboard.createAdapter(), /** * 廣告功能管理 * @type {Ad} */ ad : Ad.createAdapter(), }
這裏面除了用到@type
關鍵字以外,還用到在{}
中「|
」符號的用法。這樣的用法表明所標記的字段多是多種類型的,尤爲適用於我這段代碼中的狀況,即一個工廠方法可能會返回屬於某個父類的任何子類對象,此時若是僅使用父類類型標記這個字段,則在使用時IDE沒法提示出子類中的特殊方法,因此用了多種可能的類型標記後,IDE將會把全部可能類型中的提示信息都提示出來。此時的提示信息以下圖小程序
還有另一種方法定義一個對象中每個字段的類型和註釋,並且能夠複用,看上去更爲專業,那就是@typedef
關鍵字,下面就是用@typedef
關鍵字從新書寫的zy
對象的JSDoc:微信小程序
/** * @typedef {object} ZY * @property {number} version sdk版本號 * @property {Share|ShareWX} share 分享功能管理 * @property {CommonUtils} commonUtils 通用工具集,如網絡請求,彈框顯示等 * @property {Platform|PlatformWX} platform 平臺功能管理,如登陸,用戶信息等 * @property {Leaderboard} leaderboard 排行榜功能管理 * @property {Ad} ad 廣告功能管理 */ /** * @type {ZY} */ let zy = {}
上半部分是用@typedef
關鍵字定義了一個全新的類型ZY
,而且把類型中的每一個字段都預先定義好。而後下半部分zy對象上方用JSDoc聲這個對象的類型是ZY
。這種用法適合用在能夠複用的類型對象上,或者其內部字段沒有所有出如今字面上,或者沒有集中出如今一塊區域時。微信
下面又出現了另外一個問題,VSCode是根據文件模塊的依賴關係來導入其餘文件中的JSDoc的,好比A.js中require("B.js")
,則B.js中的JSDoc信息就能夠在A.js的JSDoc中使用,也能在A.js的代碼提示中顯示。但偶爾會遇到一些狀況,從邏輯上A.js中並不須要require("B.js")
,而在編碼中卻須要使用B.js文件中的JSDoc。若是由於這種需求就額外的require("B.js")
,就會破壞了代碼正常的依賴關係。因而就出現了以下這種用法:
/** * @typedef {import("B.js")} B */
這種方法至關於用JSDoc的方式引入的B.js文件,並將B.js中的模塊定義爲類型B。
最後奉上VSCode官方關於對JSDoc提示功能的支持文檔地址
https://github.com/Microsoft/...
https://code.visualstudio.com...
JSDoc本來是一個爲JavaScript生成文檔的工具,其語法遠比VSCode目前支持提示功能所用到的語法要多,有興趣能夠了解一下原生的JSDoc
http://www.css88.com/doc/jsdoc/
最後嗶嗶兩句,入技術圈五六年來第一次發博,也是被不少資深博主的感化,發博一方面是分享本身技術方面的心得,分享過程當中得到更多,一方面是提升本身書面表達能力。但入一個坑總得一步一步的入,因此先從無關緊要的雕蟲小技開始。