写好你的注释之 JSDoc

简介: 好的代码,注释肯定不能少,就目前而言基于 vue 的项目大部分都是使用的 vue2,vue2 相对于 ts 的支持没有那么完善,大部分包括我目前工作所在的团队,使用的 vue 版本都是采用 vue2

好的代码,注释肯定不能少,就目前而言基于 vue 的项目大部分都是使用的 vue2vue2 相对于 ts 的支持没有那么完善,大部分包括我目前工作所在的团队,使用的 vue 版本都是采用 vue2 并且不带 ts 支持,对于曾经用过或者习惯使用强类型的,难以离开 IDE 编码提示的人来说,这其实很难受,那么目前 vue2 项目可以通过 JSDoc 通过加注释的方式去过渡类型,配合 IDE 在某些情况能够达到使用 typescript 差不多的体验

最新版本更新了 JS 常见注释的写法和小细节

定义

关于 JSDoc 的相关定义可以参考这个链接,讲的挺多,甚至有很多用不上,可以考虑当成一本字典

用法

前端我用过的 IDE 时间比较长的只有 VS CodeWebstorm,先不去纠结它们的好坏,它们对方法的注释都可以使用 JSDoc,如下动图

常规

没有像 ts 那种环境的约束的话,还是很难让人有动力去写注释的,所以一般人写的注释都是写个 string/number/boolean 啥的,就是类似下面的情况

常用的就是这些,用来写下约束一下表单还是很好用的,还有数组之类的可以加上去尝试一下

二维数组也可以使用

可选参数

  1. @param {type} [p] 可选参数
  2. @param {type=} p 可选参数

例子如下

/**
 * demo
 * @param {string} a
 * @param {string} [b]
 * @param {boolean=} c
 */
function foo(a, b, c) {}

效果如下

IMG

参数默认值

  1. @param {type} [p=defaultValue] 参数默认值

例子如下

/**  
 * demo * @param {string} a  
 * @param {string} b  
 * @param {boolean} [c=false]  
 */  
function foo(a, b, c) {}

效果如下

IMG

PS: VS Code 对默认值的支持不够,效果如下

IMG

非常规

数组结构

当参数为数组时可以做到对其每个元素进行详细描述,格式如下

/**
 * 数组参数:
 * @param {array} arr 参数描述
 * @param {string} arr[0] 参数描述
 * @param {number} [arr[1]=undefined] 参数描述
 */

例子如下

/**
 * demo
 * @param {Array} arr
 * @param {string} arr[0]
 * @param {string} [arr[1]=123]
 */
function foo(arr) {}

效果如下

IMG

对于数组的注释,我个人感觉一般,不能达到 TS 的效果,不建议对数组参数里面的每个索引值进行描述,有可能会引发歧义

对象结构

暂时没有找到一个很专业的名词来介绍这部分,姑且就用它的使用范围来介绍,对象结构就是,某个参数可能是一个固定的结构的对象,类似于

{
  name: 'steven',
  age: 21
}

像这种情况,注释可以这样写

/**
 * demo
 * @param {{name: string, age: number}} a
 * @returns {number}
 */
function foo(a) {
  return 2;
}

还算不错的提示

用在返回上面也是很方便的

但是 JSDoc 到了这一步,格式化就没有很方便了,并不会对其中的结构体做特定的格式化(包括 WebStorm),这也算是很少有人去写这方面注释的一个原因,没有规范的定时炸弹,如果能出一个插件去补全这块,说不定可以激发前端程序员在非 ts 项目写上两句注释的动力

函数/方法注释

如果你的方法参数是 Object 形式,像上面的写法,会让维护者不解其中的意思,如下

/**
 * demo
 * @param {{name: string, age: number}} a
 * @returns {number}
 */
function foo(a) {
  return 2;
}
// name 是什么的名字呢?

所以可以采用另一种描述 Object 中各项的描述,如下

/**
 * demo
 * @param {Object} a
 * @param {string} a.name 回复人的名字
 * @param {number} a.age 回复人的年龄
 * @returns {number}
 */
function foo(a) {
  return 2;
}

WebStorm 效果

IMG

可以看到注释和类型,非常的不错

VS Code

同样的代码在 VS Code 上是这样的

IMG

并没有对应的属性注释,如果是下面这种写法就可以了

/**
 * demo
 * @param {{name: string, age: number}} a
 * @param {string} a.name 回复人的名字
 * @param {number} a.age 回复人的年龄
 * @returns {number}
 */
 function foo(a) {
  return 2;
}

foo({ name: "张三", age: 22 });

IMG

但这样就有点麻烦了,我建议采用在 WebStorm 的写法,在 VS Code 编码时,就采用跳转的方式查看注释,类似下面这种效果

使用 Object 作为参数,一般用在配置项的场景
  1. 有些函数的参数并不是作为算法的输入,而是对算法的某些分支条件判断之用,比如 Boolean
function fun(node, isShow, isRed = false, data) {/* ... */};
// 调用时
fun(element, true, false, "123");
// 即使有默认值的存在仍然无法跳过 isRed
// 用配置项就可以解决这个问题
function fun(option) {
    const {node, isShow, isRed = false, data} = option;
}
// 调用时
fun({node: element, isShow: true, data: "123"})
  1. 对于一些硬编码或者枚举值参数可以解释它的具体意思,如上例子
  2. 方法重载,比如上面那个例子,我既想用 fun(node) 又想用 fun(data)isShow/isRed 可能是可选参数,使用配置型参数设计就可以解决

    1. fun({node: element}) | fun({data: '123'})

更多关于参数的设计,请参考JavaScript编码规范 - 3.8.2 参数设计

自定义类型

有些时候我们可能需要使用复用一些结构体,可以使用 JSDoc 封装,如下

/**
 * 包含姓名和年龄的对象
 * @typedef {Object} Person
 * @property {string} name - 姓名
 * @property {number} age - 年龄
 */
/**
 * @type {Person} person
 */
 const person = {
   name: 'steven',
   age: 21
}

跨文件使用

// ./@types/index
/**
 * 包含姓名和年龄的对象
 * @typedef {Object} Person
 * @property {string} name - 姓名
 * @property {number} age - 年龄
 */
/**
 * @type {Person} Person
 */
// ./t.js
/**
 * @typedef {import('./@types/index').Person}
 */
/**
 * demo
 * @param {Person} a
 * @returns
 */
function foo(a) {
  return 2;
}

Vs Code 在这块的注释方面就比不上 WebStorm

JSDoc 在复用这方面,就不如 typescript 好用了,说实话,如果你的项目都需要用到这种类型了,应该尽快考虑是否应该使用 typescriptJSDoc 的生态方面还是比不过 typescript 的,而且两者写法差距蛮大,一旦写得多了,调头比较难

接口

接口 API 的注释还是挺重要的,如果 JSDoc 能用在这上面还是挺方便的,其示例如下

/**
 * demo
 * @returns {Promise<{data:{name: string, age: number}}>}
 */
function foo() {
  return new Promise((resolve, reject) => {
    resolve({ data: { name: "steven", age: 21 } });
  });
}

效果还行

总结

偶尔使用 JSDoc 写点简单的注释还行,但是复杂的项目和类型,JSDoc 和它的生态未必能够撑得住

参考资料

  1. JSDoc 中文文档
  2. 模板使用自定义类型_你不知道的类型检查(JSDoc版)
  3. JavaScript 编码规范 - 2.4.8 函数/方法注释
  4. JavaScript编码规范 - 3.8.2 参数设计
相关文章
|
1月前
|
编译器 开发者
Zig 注释
Zig 注释
27 1
|
JavaScript 前端开发 C#
js基础③—注释、快捷键、命名规则、打印、面向对象?
head标签中添加<script type="text/javascript"></script>
|
JavaScript
js 高级注释(模块注释,class注释,函数注释等)
js 高级注释(模块注释,class注释,函数注释等)
216 0
|
JavaScript 前端开发
JavaScript 代码结构:语句、分号和注释
JavaScript 代码结构:语句、分号和注释
200 0
JavaScript 代码结构:语句、分号和注释
|
C# 编译器 自然语言处理
c#小灶——注释和代码规范
c#小灶——注释和代码规范为什么要写注释?早上我写完了代码,我和我的朋友们都能看懂,到了晚上,我还能看懂,一周后,就只有上帝能看懂了…… 将来我们写的代码量是很大的,代码又不像我们自然语言这么好理解,可能过段时间我们就不认识自己的代码了,所以我们要养成写注释的好习惯。
1030 0
|
JavaScript 前端开发 C++
使用JSDoc提高代码的可读性
工作了四年多,基本上都在围绕着 JavaScript 做事情。 写的代码多了,看的代码也多了,由衷的觉得,写出别人看不懂的代码并不是什么能力,写出所有人都能读懂的代码,才是真的牛X。 众所周知, JavaScript 是一个弱类型的脚本语言,这就意味着,从编辑器中并不能直观的看出这段代码的作用是什么,有些事情只有等到代码真正的运行起来才能够确定。
7465 0