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

相关推荐
黄尚圈圈25 分钟前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水1 小时前
简洁之道 - React Hook Form
前端
正小安3 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch5 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光5 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   5 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   5 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web5 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常5 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇6 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器