弱类型脚本语言的代码提示功能一直是开发者一个隐隐的痛点,没有它也不是不能干活,可是常常由于出现拼写错误或不经意的修改致使的变量丢失而耗费无畏的时间在与业务逻辑无关的地方。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/
最后哔哔两句,入技术圈五六年来第一次发博,也是被不少资深博主的感化,发博一方面是分享本身技术方面的心得,分享过程当中得到更多,一方面是提升本身书面表达能力。但入一个坑总得一步一步的入,因此先从无关紧要的雕虫小技开始。