写好你的注释之 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月前
DTL注释
DTL注释。
8 1
|
1月前
|
编译器 C++
C++ 注释
C++ 注释
12 0
|
1月前
|
XML 程序员 编译器
C#注释
C#注释
18 0
|
1月前
|
C++
C++注释
C++注释
8 0
|
11月前
|
编译器 C++
C++ 注释
【摘要】 C++ 注释程序的注释是解释性语句,您可以在 C++ 代码中包含注释,这将提高源代码的可读性。所有的编程语言都允许某种形式的注释。C++ 支持单行注释和多行注释。注释中的所有字符会被 C++ 编译器忽略。C++ 注释一般有两种:// - 一般用于单行注释。/* ... */ - 一般用于多行注释。注释以 // 开始,直到行末为止。例如:实例#include <iostream>using n...
注释
注释
66 0
|
程序员
笑出腹肌的注释,就怕你不敢用!
笑出腹肌的注释,就怕你不敢用!
笑出腹肌的注释,就怕你不敢用!
|
程序员
10 个雷人的注释,就怕你不敢用!
本文来源网络: 1、码农何苦为难穷逼 2、删了就无法运行,我也不知道为什么
10 个雷人的注释,就怕你不敢用!
|
C++
C++学习001-注释
天了噜,感觉自己最近好堕落啊, 在等待项目任务书到来的时候,在来好好学习学习C++ 今天来学习一下C++的注释风格 编写环境 Qt 5.7
79 0
fbh
|
前端开发
less学习——注释
CSS 形式的注释在 LESS 中是依然保留的: /* Hello, I'm a CSS-style comment */ .
fbh
1011 0

热门文章

最新文章