【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官方网站。

相关推荐
zttbee4 小时前
echarts图表tooltip色块失效
前端·javascript·echarts
excel6 小时前
IndexNow:让搜索引擎更快发现网站更新的主动通知协议
前端·后端·架构
子兮曰6 小时前
CSS 复现 23 种设计风格:从拟物到液态玻璃的成本阶梯与兜底写法【实战】
前端·css·视觉设计
虚无境7 小时前
如何用AI帮我写出实用的插件
前端·javascript·ai编程
柳杉7 小时前
从数字化到数智化:3D 可视化大屏的下一个五年
前端·ai编程·数据可视化
风骏时光牛马8 小时前
从零到实战:AI全栈学习进阶路线
前端
FRing038 小时前
JavaScript入门到精通二十六(变量提升、函数剩余参数、展开运算符、ES6箭头函数)
开发语言·前端·javascript·es6·箭头函数
用户360055579008 小时前
Kestrel_VLLM - 15 · decode 优化四连击:19ms → 8ms
前端
IT_陈寒9 小时前
JavaScript的闭包陷阱,这个坑我躺了三天才爬出来
前端·人工智能·后端
计算机魔术师9 小时前
Microsoft Research 与合作者证明 31 年历史的 KLS 猜想
前端