【JSDoc】都2024年了,你不会还在用纯文本写注释吧

使用背景

在很多存量的项目中,可能很多项目都没有上ts,以及开发人员的注释写的云里雾里。比如以下场景,当你接手这种代码时,你会不会跟我一样想params要传什么?这个函数有没有返回值?返回值是什么?

javascript 复制代码
// 获取用户信息
function getUser (params) {
    // code
}

当你跟我有相同的疑问时,我们何妨不花几分钟来了解今天的主角jsdoc,来优化我们的🪨山代码呢~~

主要关键字使用说明

@typedef

语法: [<type>] <namepath>

使用场景:声明一个自定义类型,可以用于函数入参出参,类型于typesript的type定义

javascript 复制代码
/**
 * @typedef {Object} User
 * @property {string} User.name - 用户姓名
 * @property {number} User.age - 用户年龄
 */
 
 
 /**
 * @param {User} 查询的用户
 * @returns {number} 用户年龄
 */
function getUserAge(user) {
  return user.age
}

效果:调用函数就会根据定义的类型来进行智能推断


@enum

语法:@enum <type> 使用场景:定义一个对象为枚举类型,可以直接使用该对象作为入参类型,一般配合@readonly使用,因为枚举值正常来说是不能被更改的。

javascript 复制代码
/**
 * @readonly
 * @enum {'1' | '2'}
 */
const SEX = {
  MALE: '1',
  FEMALE: '2',
}

@callback

语法:@callback <namepath>

使用场景:定义回调函数的类型,以充当其他函数的入参类型。 比单纯使用Function类型来定义入参会更加的清晰知道回调函数需要几个入参,以及出参。

javascript 复制代码
/**
 * 过滤特定年龄用户回调函数
 * @callback RequestUserFilterCallback
 * @param {User[]} users 用户数组
 * @param {number} limitAge 年龄条件
 * @returns {User[]} 符合条件的用户
 */


/**
 * 获取用户
 * @param {RequestUserFilterCallback} cb 过滤函数
 */
async function fetchUser (cb) {
  const users = await fetch('get/users')
  return cb(users, 18)
}

fetchUser((users, limitAge) => users.age <= limitAge)

效果:调用函数的时候就会有对应的回调类型提示


@param

语法:@param [<type>] <name> [<description>]

使用场景:建议每个函数的入参都使用@param来进行标注,不仅可以使开发者清晰地知道每个入参的意义,而且在使用函数的时候编辑器也会有对应的类型提示。

必填参数使用示例

javascript 复制代码
// 这里的类型可以使用javascript的基本类型或者自定义类型

/**
 * @readonly
 * @enum {'1' | '2'}
 */
const SEX = {
  MALE: '1',
  FEMALE: '2',
}

/**
 * 自定义用户类型
 * @typedef {Object} User
 * @property {string} User.name - 用户姓名
 * @property {number} User.age - 用户年龄
 */

/**
 * 给用户增加性别
 * @param {User} user 查询的用户
 * @param {SEX} sex 用户性别
 * @returns {User & {sex: SEX}} 具有性别属性的用户
 */
function addUserSex(user, sex) {
  return {...user, sex}
}

效果:写好函数入参,出参的类型标注,编辑器会获得类型提示,减少开发理解和使用成本。

可选参数使用示例

给参数增加[],代表可选参数

javascript 复制代码
/**
 * 获取用户性别
 * @param {User} [user] 查询的用户,可能为空
 * @returns {SEX | null}
 */
function getUserSex (user) {
  if (user) {
    return user.sex
  }
  return null
}

getUserSex()

效果:


@this

语法:@this 声明的对象

使用场景:声明当前函数的this指向,在非纯函数的编程环境中,this的指向经常是编辑器无法推断的,而且对其他开发人员也不够清晰,使用@this可以清晰地告诉外界当前函数的this指向

javascript 复制代码
/**
 * @description jsdoc this 使用示例
 * @this Vue
 */
function testThis () {
  this.$alert('123')
}

效果:此时调用函数时编辑器会识别并且有智能提醒


@todo

语法:@todo 描述要实现的事情

使用场景:当版本功能还未完成时,用@todo标记后续待实现的功能。

javascript 复制代码
/**
 * 实现一个使用例子
 * @todo 增加例子
 * @todo 增加注释
 */
function createExample () {}

@example

使用场景:给函数增加使用例子,特别是参数较多的函数,建议多种情况的例子都标注好。

javascript 复制代码
/**
 * 两数相加
 * @param {number} num1 相加数字
 * @param {number} num2 相加数字
 * @returns {number} 两数之和
 * @example
 * add(1, 2) // 3
 */
function add (num1, num2) {
  return num1 + num2
}

效果:调用函数的时候可以看到标注的例子如何进行使用


@deprecated

语法:@deprecated [废弃的原因及指引] 使用场景:当版本升级后,原有代码需要逐步替换时,标注好什么代码在日后不使用以及指引如何切换到新代码,对于版本升级/重构代码时可让团队开发人员清晰知道被标注的代码已废弃。

javascript 复制代码
/**
 * @deprecated 从版本1.0后废弃,登录功能请使用loginV2函数
 */
function login () {}

效果:调用被标注的内容时,编辑器会自动识别到该方法已废弃,并且展示废弃的指引内容。


总结

使用jsdoc有以下的优势

  1. 提高代码的可读性,提高项目代码可维护性
  2. 可以在不引入typescript的同时,使用typescript的类型标注,代码静态提示等功能,这在一些老项目的时候非常实用
  3. 对项目代码无副作用,例如运行构建变慢,代码改造等都无需担心
  4. 配合现代编辑器可以有很好的智能提醒,减少因手写错误等低级错误的产生

注意事项

  1. jsdoc并不能代替typescript的功能,它只是一个规范的约束,并不能保证类型安全。
  2. 建议公用代码及公用组件一定要进行良好的类型标注及例子说明。

上述例子只是列举来一些比较常用的场景,还有更多深入的玩法可以参考jsdoc官方网站

相关推荐
四喜花露水19 分钟前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy28 分钟前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
web Rookie1 小时前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust1 小时前
css:基础
前端·css
帅帅哥的兜兜1 小时前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3
yi碗汤园1 小时前
【一文了解】C#基础-集合
开发语言·前端·unity·c#
就是个名称1 小时前
购物车-多元素组合动画css
前端·css
编程一生2 小时前
回调数据丢了?
运维·服务器·前端
丶21362 小时前
【鉴权】深入了解 Cookie:Web 开发中的客户端存储小数据
前端·安全·web
Missmiaomiao3 小时前
npm install慢
前端·npm·node.js