JSDoc 标签完全指南

2 阅读12分钟

JSDoc 是一种用于 JavaScript 代码文档的注释格式,类似于 Java 的 Javadoc。通过使用特殊的标签(以 @ 开头),开发者可以为函数、类、方法等代码元素提供结构化的文档。本指南将详细介绍各种 JSDoc 标签及其使用方法。

目录

基础概念

JSDoc 注释通常位于代码元素之前,以 /** 开始,以 */ 结束。每行前面通常有一个星号 *

/**
 * 这是一个 JSDoc 注释
 * @标签 值
 */

描述性标签

@description

提供对代码元素的详细描述。这是注释的主体部分。

/**
 * @description 计算两个数字的和
 */
function add(a, b) {
    return a + b;
}

@summary

提供简短的概述。通常用于长描述之前。

/**
 * @summary 计算两数之和
 * @description 接受两个数字参数,返回它们的加和
 */
function add(a, b) {
    return a + b;
}

@example

提供如何使用代码的示例。

/**
 * 计算两个数字的和
 * @example
 * // 返回 3
 * add(1, 2);
 */
function add(a, b) {
    return a + b;
}

@since

指明功能是从哪个版本开始添加的。

/**
 * 计算两个数字的和
 * @since 1.0.0
 */
function add(a, b) {
    return a + b;
}

@deprecated

表示该功能已经被废弃,通常会提供替代方案。

/**
 * 计算两个数字的和
 * @deprecated 使用 sum() 代替
 */
function add(a, b) {
    return a + b;
}

@todo

标记需要完成的工作。

/**
 * 计算两个数字的和
 * @todo 添加对非数字输入的验证
 */
function add(a, b) {
    return a + b;
}

@author

指定代码的作者。

/**
 * 数学工具库
 * @author 张三 <zhangsan@example.com>
 */
const MathUtils = {};

@version

指定代码的版本。

/**
 * 数学工具库
 * @version 1.0.0
 */
const MathUtils = {};

@copyright

提供版权信息。

/**
 * 数学工具库
 * @copyright 2025 Example Corp.
 */
const MathUtils = {};

@license

提供许可证信息。

/**
 * 数学工具库
 * @license MIT
 */
const MathUtils = {};

类相关标签

@class

标记一个函数作为构造函数,用于创建新的类。

/**
 * 表示一个人的类
 * @class
 */
function Person(name) {
    this.name = name;
}

@classdesc

为类提供描述,与 @class 一起使用。

/**
 * @class
 * @classdesc 表示一个有姓名的人
 */
function Person(name) {
    this.name = name;
}

@constructor

标记一个函数为构造函数,与 @class 类似。

/**
 * @constructor
 * @param {string} name - 人的姓名
 */
function Person(name) {
    this.name = name;
}

@hideconstructor

表示构造函数应该在文档中隐藏。

/**
 * 单例模式的日志记录器
 * @hideconstructor
 */
class Logger {
    constructor() {
        if (Logger.instance) {
            return Logger.instance;
        }
        Logger.instance = this;
    }
}

@constructs

表示一个函数将会把对象添加到另一个对象的 prototype 上。

/**
 * @class
 */
function Person() {}

/**
 * @constructs
 */
Person.prototype.initialize = function(name) {
    this.name = name;
};

@instance

标记一个变量作为类的实例。

/**
 * @class
 */
function Person() {}

/**
 * 默认的人实例
 * @instance
 */
const defaultPerson = new Person();

@interface

标记一个函数为接口。

/**
 * 可比较对象的接口
 * @interface
 */
function Comparable() {}

/**
 * 比较此对象与另一个对象
 * @method
 * @name Comparable#compare
 * @param {Object} other - 要比较的对象
 * @returns {number} 比较结果
 */

函数相关标签

@function

标记一个对象为函数。

/**
 * 计算两个数字的和
 * @function
 */
const add = function(a, b) {
    return a + b;
};

@method

标记一个对象为方法,通常是类或对象的一部分。

/**
 * @class
 */
function MathUtils() {}

/**
 * 计算两个数字的和
 * @method
 */
MathUtils.prototype.add = function(a, b) {
    return a + b;
};

@param

描述函数参数。

/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
function add(a, b) {
    return a + b;
}

@argument

@param 的别名,描述函数参数。

/**
 * 计算两个数字的和
 * @argument {number} a - 第一个数字
 * @argument {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
function add(a, b) {
    return a + b;
}

@returns

描述函数的返回值。

/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
function add(a, b) {
    return a + b;
}

@throws

描述函数可能抛出的异常。

/**
 * 除法运算
 * @param {number} a - 被除数
 * @param {number} b - 除数
 * @returns {number} 除法结果
 * @throws {Error} 当除数为 0 时抛出异常
 */
function divide(a, b) {
    if (b === 0) {
        throw new Error("除数不能为 0");
    }
    return a / b;
}

@async

标记一个函数为异步函数。

/**
 * 异步获取用户数据
 * @async
 * @param {number} id - 用户 ID
 * @returns {Promise<Object>} 用户数据
 */
async function getUser(id) {
    const response = await fetch(`/api/users/${id}`);
    return response.json();
}

@generator

标记一个函数为生成器函数。

/**
 * 生成连续的数字
 * @generator
 * @yields {number} 连续的数字
 */
function* numberGenerator() {
    let i = 0;
    while (true) {
        yield i++;
    }
}

@yields

描述生成器函数的 yield 值。

/**
 * 生成斐波那契数列
 * @generator
 * @yields {number} 斐波那契数列中的下一个数
 */
function* fibonacci() {
    let [prev, curr] = [0, 1];
    while (true) {
        yield curr;
        [prev, curr] = [curr, prev + curr];
    }
}

@callback

描述回调函数的类型。

/**
 * 回调函数,处理操作结果
 * @callback resultCallback
 * @param {Error|null} err - 错误对象,如果没有错误则为 null
 * @param {Object} [result] - 操作结果,如果有错误则不存在
 */

/**
 * 执行异步操作
 * @param {Object} options - 操作选项
 * @param {resultCallback} callback - 操作完成后的回调函数
 */
function doAsync(options, callback) {
    // 实现...
}

@overload

标记函数有多个实现(重载)。

/**
 * @overload
 * @param {string} name - 人的姓名
 */

/**
 * @overload
 * @param {Object} options - 人的选项
 * @param {string} options.name - 人的姓名
 */

/**
 * 创建一个人
 * @param {string|Object} nameOrOptions - 姓名或配置对象
 */
function createPerson(nameOrOptions) {
    // 实现...
}

模块和命名空间

@module

标记一个文件为模块。

/**
 * 数学工具模块
 * @module math-utils
 */

/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
export function add(a, b) {
    return a + b;
}

@exports

标记模块导出的内容。

/**
 * 数学工具模块
 * @module math-utils
 */

/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 * @exports
 */
function add(a, b) {
    return a + b;
}

module.exports = { add };

@namespace

标记一个对象为命名空间。

/**
 * 数学工具命名空间
 * @namespace
 */
const MathUtils = {};

/**
 * 计算两个数字的和
 * @function
 * @memberof MathUtils
 */
MathUtils.add = function(a, b) {
    return a + b;
};

@memberof

标记一个符号属于某个父符号。

/**
 * 数学工具命名空间
 * @namespace
 */
const MathUtils = {};

/**
 * 计算两个数字的和
 * @function
 * @memberof MathUtils
 */
MathUtils.add = function(a, b) {
    return a + b;
};

@requires

标记模块依赖。

/**
 * 用户服务模块
 * @module user-service
 * @requires axios
 * @requires ./config
 */
const axios = require('axios');
const config = require('./config');

类型标签

@type

指定变量的类型。

/**
 * 数组中的最大元素数量
 * @type {number}
 */
const MAX_ITEMS = 100;

@typedef

定义自定义类型。

/**
 * 用户对象类型
 * @typedef {Object} User
 * @property {string} id - 用户 ID
 * @property {string} name - 用户名
 * @property {string} email - 邮箱地址
 */

/**
 * 当前用户
 * @type {User}
 */
const currentUser = { id: '1', name: 'admin', email: 'admin@example.com' };

@template

定义泛型类型参数。

/**
 * 通用列表类
 * @template T 列表元素的类型
 */
class List {
    /**
     * @param {T[]} items - 初始元素
     */
    constructor(items) {
        this.items = items;
    }
    
    /**
     * 添加元素到列表
     * @param {T} item - 要添加的元素
     */
    add(item) {
        this.items.push(item);
    }
}

@var

标记一个变量。

/**
 * PI 常量
 * @var {number}
 */
const PI = 3.14159;

@constant

标记一个常量。

/**
 * 最大尝试次数
 * @constant {number}
 */
const MAX_ATTEMPTS = 3;

@default

指定参数的默认值。

/**
 * 格式化字符串
 * @param {string} str - 要格式化的字符串
 * @param {Object} [options={}] - 格式化选项
 * @param {boolean} [options.uppercase=false] - 是否转为大写
 * @default options={}
 */
function format(str, options = {}) {
    // 实现...
}

@property

描述对象的属性。

/**
 * 配置对象
 * @typedef {Object} Config
 * @property {string} host - 服务器主机名
 * @property {number} port - 服务器端口
 * @property {Object} auth - 认证信息
 * @property {string} auth.username - 用户名
 * @property {string} auth.password - 密码
 */

@prop

@property 的别名。

/**
 * 配置对象
 * @typedef {Object} Config
 * @prop {string} host - 服务器主机名
 * @prop {number} port - 服务器端口
 */

继承和关系标签

@extends

表示一个类继承自另一个类。

/**
 * 基础动物类
 * @class
 */
class Animal {
    constructor(name) {
        this.name = name;
    }
}

/**
 * 猫类
 * @class
 * @extends Animal
 */
class Cat extends Animal {
    constructor(name) {
        super(name);
    }
    
    meow() {
        console.log('喵喵!');
    }
}

@augments

@extends 的别名。

/**
 * 基础动物类
 * @class
 */
class Animal {
    constructor(name) {
        this.name = name;
    }
}

/**
 * 猫类
 * @class
 * @augments Animal
 */
class Cat extends Animal {
    constructor(name) {
        super(name);
    }
}

@implements

表示一个类实现了一个接口。

/**
 * 可比较接口
 * @interface
 */
class Comparable {
    /**
     * 比较方法
     * @param {Object} other - 要比较的对象
     * @returns {number} 比较结果
     */
    compare(other) {}
}

/**
 * 整数类
 * @class
 * @implements Comparable
 */
class Integer {
    constructor(value) {
        this.value = value;
    }
    
    /**
     * 比较两个整数
     * @param {Integer} other - 要比较的整数
     * @returns {number} 比较结果
     */
    compare(other) {
        return this.value - other.value;
    }
}

@mixes

表示一个对象混入了其他对象的功能。

/**
 * 日志混入
 * @mixin
 */
const LoggerMixin = {
    /**
     * 记录日志
     * @param {string} message - 日志消息
     */
    log(message) {
        console.log(`[LOG] ${message}`);
    }
};

/**
 * 用户服务
 * @class
 * @mixes LoggerMixin
 */
class UserService {
    constructor() {
        Object.assign(this, LoggerMixin);
    }
    
    getUser(id) {
        this.log(`获取用户 ${id}`);
        // 实现...
    }
}

@inheritdoc

表示继承上级元素的文档。

/**
 * 基础控制器
 * @class
 */
class BaseController {
    /**
     * 处理请求
     * @param {Object} req - 请求对象
     * @param {Object} res - 响应对象
     */
    handle(req, res) {
        // 基础实现
    }
}

/**
 * 用户控制器
 * @class
 * @extends BaseController
 */
class UserController extends BaseController {
    /**
     * @inheritdoc
     */
    handle(req, res) {
        // 特定实现
    }
}

@lends

表示将对象的所有属性归属于某个类。

/**
 * 创建一个人的类
 * @class
 */
var Person = function(name) {
    this.name = name;
};

/**
 * @lends Person.prototype
 */
var proto = {
    /**
     * 获取姓名
     * @returns {string} 姓名
     */
    getName: function() {
        return this.name;
    }
};

Object.assign(Person.prototype, proto);

@borrows

表示一个对象借用另一个对象的文档。

/**
 * 格式化工具
 * @namespace
 */
const Formatter = {
    /**
     * 格式化日期
     * @param {Date} date - 要格式化的日期
     * @returns {string} 格式化后的日期字符串
     */
    formatDate(date) {
        return date.toISOString().split('T')[0];
    }
};

/**
 * 日期工具
 * @namespace
 * @borrows Formatter.formatDate as format
 */
const DateUtils = {
    format: Formatter.formatDate
};

访问控制标签

@public

表示成员为公开的(默认)。

/**
 * @class
 */
class Person {
    /**
     * 获取姓名
     * @public
     * @returns {string} 姓名
     */
    getName() {
        return this.name;
    }
}

@private

表示成员为私有的。

/**
 * @class
 */
class Person {
    constructor(name) {
        /**
         * 姓名
         * @private
         * @type {string}
         */
        this._name = name;
    }
}

@protected

表示成员为受保护的。

/**
 * @class
 */
class Person {
    constructor(name) {
        /**
         * 姓名
         * @protected
         * @type {string}
         */
        this._name = name;
    }
}

@access

指定访问级别,可以是 publicprivateprotected

/**
 * @class
 */
class Person {
    constructor(name, age) {
        /**
         * 姓名
         * @access public
         * @type {string}
         */
        this.name = name;
        
        /**
         * 年龄
         * @access private
         * @type {number}
         */
        this._age = age;
    }
}

@readonly

表示成员为只读的。

/**
 * @class
 */
class Person {
    constructor(name) {
        /**
         * 唯一标识符
         * @readonly
         * @type {string}
         */
        this.id = Math.random().toString(36).substr(2, 9);
        
        this.name = name;
    }
}

@package

表示成员的可见性为包级别。

/**
 * @class
 */
class Person {
    constructor(name) {
        /**
         * 内部 ID
         * @package
         * @type {string}
         */
        this._internalId = Math.random().toString(36).substr(2, 9);
        
        this.name = name;
    }
}

其他标签

@abstract

标记一个方法为抽象方法,需要在子类中实现。

/**
 * 抽象形状类
 * @abstract
 * @class
 */
class Shape {
    /**
     * 计算面积
     * @abstract
     * @returns {number} 面积
     */
    area() {
        throw new Error('抽象方法必须在子类中实现');
    }
}

@alias

为成员提供别名。

/**
 * 数学工具
 * @namespace
 */
const MathUtils = {};

/**
 * 计算两个数字的和
 * @function
 * @alias MathUtils.add
 */
MathUtils.add = function(a, b) {
    return a + b;
};

@event

描述事件。

/**
 * 用户类
 * @class
 */
class User {
    /**
     * 用户登录事件
     * @event User#login
     * @type {Object}
     * @property {string} username - 登录的用户名
     * @property {Date} time - 登录时间
     */
     
    login(username, password) {
        // 登录逻辑...
        
        /**
         * 登录事件
         * @event User#login
         */
        this.emit('login', {
            username,
            time: new Date()
        });
    }
}

@emits

标记方法发出的事件。

/**
 * 用户类
 * @class
 */
class User {
    /**
     * 用户登录
     * @param {string} username - 用户名
     * @param {string} password - 密码
     * @emits User#login
     */
    login(username, password) {
        // 登录逻辑...
        this.emit('login', { username, time: new Date() });
    }
}

@fires

@emits 的别名。

/**
 * 用户服务
 * @class
 */
class UserService {
    /**
     * 创建新用户
     * @param {Object} data - 用户数据
     * @fires UserService#userCreated
     */
    createUser(data) {
        // 创建用户逻辑...
        this.emit('userCreated', { user: newUser });
    }
}

@listens

标记类或方法监听的事件。

/**
 * 日志服务
 * @class
 */
class LogService {
    constructor(userService) {
        /**
         * 记录用户创建
         * @listens UserService#userCreated
         */
        userService.on('userCreated', this.logUserCreation.bind(this));
    }
    
    /**
     * 记录用户创建
     * @param {Object} event - 事件对象
     */
    logUserCreation(event) {
        console.log(`用户已创建: ${event.user.name}`);
    }
}

@file

提供当前文件的描述。

/**
 * @file 数学工具库 - 提供各种数学计算函数
 */

/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
function add(a, b) {
    return a + b;
}

@fileoverview

@file 的别名。

/**
 * @fileoverview 用户管理模块 - 处理用户相关操作
 */

/**
 * 用户类
 * @class
 */
class User {
    constructor(name) {
        this.name = name;
    }
}

@this

描述 this 关键字在函数中的含义。

/**
 * 任务方法
 * @this {TaskRunner} TaskRunner 实例
 */
function run() {
    this.isRunning = true;
    console.log(`任务正在运行: ${this.name}`);
}

const taskRunner = {
    name: '主任务',
    isRunning: false,
    run: run
};

@global

标记一个成员为全局的。

(function() {
    /**
     * 全局错误处理函数
     * @global
     * @param {Error} error - 错误对象
     */
    window.handleError = function(error) {
        console.error('发生错误:', error);
    };
})();

@link

创建指向其他文档的链接。

/**
 * 用户管理器类
 * @see {@link UserService} 用于底层 API 调用
 */
class UserManager {
    constructor(service) {
        this.service = service;
    }
}

@linkcode

创建指向代码的链接。

/**
 * 格式化日期
 * 使用 {@linkcode DateUtils.format} 内部进行格式化
 */
function prettyDate(date) {
    return DateUtils.format(date, 'YYYY-MM-DD');
}

@linkplain

创建指向其他文档的纯文本链接。

/**
 * 用户验证
 * 详见 {@linkplain Auth.validateUser} 了解验证流程
 */
function checkUser(user) {
    return Auth.validateUser(user);
}

@see

引用其他文档项。

/**
 * 计算两个数字的和
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 * @see subtract 相反操作
 */
function add(a, b) {
    return a + b;
}

/**
 * 计算两个数字的差
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的差
 */
function subtract(a, b) {
    return a - b;
}

@tutorial

引用教程文档。

/**
 * 用户认证模块
 * @tutorial user-authentication
 */
const Auth = {
    /**
     * 登录方法
     * @param {string} username - 用户名
     * @param {string} password - 密码
     * @returns {Promise<Object>} 用户信息
     */
    login(username, password) {
        // 实现...
    }
};

@external

标记外部类或命名空间。

/**
 * jQuery 库
 * @external jQuery
 * @see {@link https://jquery.com/|jQuery}
 */

/**
 * 选择元素并添加类
 * @param {string} selector - CSS 选择器
 * @param {string} className - 要添加的类名
 * @returns {external:jQuery} jQuery 对象
 */
function selectAndAddClass(selector, className) {
    return $(selector).addClass(className);
}

@host

指定主机对象。

/**
 * @host MyLibrary
 */

/**
 * 工具函数
 * @namespace
 */
MyLibrary.utils = {};

@inner

标记成员为内部的。

/**
 * 数学工具
 * @namespace
 */
const MathUtils = {};

(function() {
    /**
     * 内部辅助函数
     * @inner
     * @param {number} x - 输入值
     * @returns {number} 处理后的值
     */
    function helper(x) {
        return x * x;
    }
    
    /**
     * 计算平方
     * @

@inner

标记成员为内部的。

/**
 * 数学工具
 * @namespace
 */
const MathUtils = {};

(function() {
    /**
     * 内部辅助函数
     * @inner
     * @param {number} x - 输入值
     * @returns {number} 处理后的值
     */
    function helper(x) {
        return x * x;
    }
    
    /**
     * 计算平方
     * @param {number} x - 要平方的数字
     * @returns {number} x 的平方
     */
    MathUtils.square = function(x) {
        return helper(x);
    };
})();

@satisfies

表示变量满足指定的类型。

/**
 * @typedef {Object} Point
 * @property {number} x - X 坐标
 * @property {number} y - Y 坐标
 */

/**
 * 创建点的函数
 * @returns {Object} 点对象
 * @satisfies {Point}
 */
function createPoint() {
    return { x: 0, y: 0 };
}

@kind

指定元素的种类。可能的值包括 class, constant, event, external, file, function, member, mixin, module, namespace, typedef 等。

/**
 * 数学常量
 * @kind namespace
 */
const MathConstants = {
    /**
     * 圆周率
     * @kind constant
     * @type {number}
     */
    PI: 3.14159
};

@name

指定元素的名称。

/**
 * 计算两个数字的和
 * @name add
 * @function
 * @param {number} a - 第一个数字
 * @param {number} b - 第二个数字
 * @returns {number} 两个数字的和
 */
const add = function(a, b) {
    return a + b;
};

@field

标记一个变量作为类或对象的字段。

/**
 * 用户类
 * @class
 */
class User {
    constructor(name) {
        /**
         * 用户名
         * @field
         * @type {string}
         */
        this.name = name;
    }
}

@static

标记一个成员为静态的。

/**
 * 用户类
 * @class
 */
class User {
    /**
     * 创建新用户
     * @static
     * @param {string} name - 用户名
     * @returns {User} 用户实例
     */
    static create(name) {
        return new User(name);
    }
    
    constructor(name) {
        this.name = name;
    }
}

@variation

标记元素的变体。

/**
 * 格式化日期
 * @variation 1
 * @param {Date} date - 日期对象
 * @returns {string} YYYY-MM-DD 格式的日期
 */
function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

/**
 * 格式化日期
 * @variation 2
 * @param {Date} date - 日期对象
 * @param {string} format - 格式字符串
 * @returns {string} 格式化后的日期
 */
function formatDate(date, format) {
    // 高级格式化实现...
}

@virtual

标记一个方法可以被子类重写。

/**
 * 基础组件类
 * @class
 */
class Component {
    /**
     * 渲染组件
     * @virtual
     * @returns {string} 渲染后的 HTML
     */
    render() {
        return '<div></div>';
    }
}

/**
 * 按钮组件
 * @class
 * @extends Component
 */
class Button extends Component {
    /**
     * 重写渲染方法
     * @returns {string} 按钮 HTML
     */
    render() {
        return '<button>点击</button>';
    }
}

复合示例

下面是一些复合示例,展示了在实际项目中多个标签如何一起使用。

模块示例

/**
 * @module user-service
 * @description 用户服务模块,提供用户管理功能
 * @author 张三 <zhangsan@example.com>
 * @version 1.2.0
 * @since 1.0.0
 * @requires axios
 * @requires ./config
 */

const axios = require('axios');
const config = require('./config');

/**
 * 用户类
 * @class
 * @classdesc 表示系统中的一个用户
 */
class User {
    /**
     * 创建用户实例
     * @constructor
     * @param {Object} data - 用户数据
     * @param {string} data.id - 用户 ID
     * @param {string} data.name - 用户名
     * @param {string} data.email - 邮箱
     */
    constructor(data) {
        /**
         * 用户 ID
         * @type {string}
         * @readonly
         */
        this.id = data.id;
        
        /**
         * 用户名
         * @type {string}
         */
        this.name = data.name;
        
        /**
         * 邮箱
         * @type {string}
         */
        this.email = data.email;
        
        /**
         * 创建时间
         * @type {Date}
         * @private
         */
        this._createdAt = new Date();
    }
    
    /**
     * 获取用户显示名称
     * @returns {string} 显示名称
     */
    getDisplayName() {
        return this.name || this.email;
    }
}

/**
 * 用户服务
 * @class
 */
class UserService {
    /**
     * 获取用户
     * @async
     * @param {string} id - 用户 ID
     * @returns {Promise<User>} 用户对象
     * @throws {Error} 如果用户不存在
     */
    async getUser(id) {
        try {
            const response = await axios.get(`${config.apiUrl}/users/${id}`);
            return new User(response.data);
        } catch (error) {
            throw new Error(`获取用户失败: ${error.message}`);
        }
    }
    
    /**
     * 创建用户
     * @async
     * @param {Object} data - 用户数据
     * @param {string} data.name - 用户名
     * @param {string} data.email - 邮箱
     * @returns {Promise<User>} 创建的用户
     * @fires UserService#userCreated
     */
    async createUser(data) {
        try {
            const response = await axios.post(`${config.apiUrl}/users`, data);
            const user = new User(response.data);
            
            /**
             * 用户创建事件
             * @event UserService#userCreated
             * @type {Object}
             * @property {User} user - 创建的用户
             * @property {Date} time - 创建时间
             */
            this.emit('userCreated', {
                user,
                time: new Date()
            });
            
            return user;
        } catch (error) {
            throw new Error(`创建用户失败: ${error.message}`);
        }
    }
}

/**
 * 默认用户服务实例
 * @type {UserService}
 * @exports
 */
module.exports = new UserService();

类型定义示例

/**
 * @typedef {Object} Address
 * @property {string} street - 街道
 * @property {string} city - 城市
 * @property {string} state - 州/省
 * @property {string} zipCode - 邮编
 * @property {string} [country='中国'] - 国家,默认为中国
 */

/**
 * @typedef {Object} Contact
 * @property {string} phone - 电话号码
 * @property {string} email - 电子邮件
 * @property {Address} address - 地址
 */

/**
 * @typedef {Object} UserDetails
 * @property {string} id - 用户 ID
 * @property {string} username - 用户名
 * @property {string} fullName - 全名
 * @property {Date} birthDate - 出生日期
 * @property {Contact} contact - 联系方式
 * @property {string[]} roles - 角色列表
 * @property {Object.<string, boolean>} permissions - 权限映射
 */

/**
 * 验证用户详情
 * @param {UserDetails} user - 用户详情
 * @returns {boolean} 是否有效
 */
function validateUser(user) {
    // 实现...
    return true;
}

回调和 Promise 示例

/**
 * 结果回调函数
 * @callback ResultCallback
 * @param {Error|null} error - 错误对象,成功时为 null
 * @param {*} [result] - 结果数据,出错时不存在
 */

/**
 * 读取文件内容
 * @param {string} path - 文件路径
 * @param {ResultCallback} callback - 回调函数
 */
function readFile(path, callback) {
    fs.readFile(path, 'utf8', callback);
}

/**
 * 异步读取文件内容(Promise 版本)
 * @param {string} path - 文件路径
 * @returns {Promise<string>} 包含文件内容的 Promise
 * @throws {Error} 如果读取失败
 */
async function readFileAsync(path) {
    return new Promise((resolve, reject) => {
        fs.readFile(path, 'utf8', (err, data) => {
            if (err) reject(err);
            else resolve(data);
        });
    });
}

模板和泛型示例

/**
 * 通用缓存类
 * @template K 键类型
 * @template V 值类型
 */
class Cache {
    constructor() {
        /**
         * 存储对象
         * @type {Map<K, V>}
         * @private
         */
        this._storage = new Map();
    }
    
    /**
     * 设置缓存项
     * @param {K} key - 键
     * @param {V} value - 值
     * @returns {this} 链式调用
     */
    set(key, value) {
        this._storage.set(key, value);
        return this;
    }
    
    /**
     * 获取缓存项
     * @param {K} key - 键
     * @returns {V|undefined} 值,不存在时为 undefined
     */
    get(key) {
        return this._storage.get(key);
    }
}

/**
 * 创建字符串缓存
 * @returns {Cache<string, string>} 字符串缓存
 */
function createStringCache() {
    return new Cache();
}

最佳实践

在使用 JSDoc 时,以下是一些推荐的最佳实践:

一致性

在整个项目中保持一致的文档风格和标签使用。

// 好的实践: 所有函数都使用相同的文档模式
/**
 * 函数 A
 * @param {string} param - 参数
 * @returns {number} 结果
 */
function functionA(param) {}

/**
 * 函数 B
 * @param {boolean} flag - 标志
 * @returns {string} 结果
 */
function functionB(flag) {}

简洁明了

保持文档简洁但信息丰富。

// 好的实践: 简洁明了
/**
 * 解析 JSON 字符串
 * @param {string} json - JSON 字符串
 * @returns {Object} 解析后的对象
 * @throws {SyntaxError} 如果 JSON 格式无效
 */
function parseJson(json) {
    return JSON.parse(json);
}

类型描述

尽可能详细地描述类型,包括复杂类型和可能的值。

/**
 * 配置对象
 * @typedef {Object} Config
 * @property {string} endpoint - API 端点
 * @property {number} [timeout=30000] - 超时时间(毫秒)
 * @property {'GET'|'POST'|'PUT'|'DELETE'} method - HTTP 方法
 * @property {Object.<string, string>} headers - HTTP 头
 */

完整的示例

为复杂功能提供示例,帮助用户理解如何使用。

/**
 * 格式化货币
 * @param {number} amount - 金额
 * @param {string} [currency='CNY'] - 货币代码
 * @param {string} [locale='zh-CN'] - 区域设置
 * @returns {string} 格式化后的货币字符串
 * @example
 * // 返回 "¥1,234.56"
 * formatCurrency(1234.56);
 * 
 * // 返回 "$1,234.56"
 * formatCurrency(1234.56, 'USD', 'en-US');
 */
function formatCurrency(amount, currency = 'CNY', locale = 'zh-CN') {
    return new Intl.NumberFormat(locale, {
        style: 'currency',
        currency: currency
    }).format(amount);
}

总结

JSDoc 是一个强大的文档生成工具,可以帮助开发者创建清晰、结构化和易于理解的代码文档。通过使用各种标签,可以描述代码的各个方面,包括:

  1. 函数和方法的参数、返回值和抛出的异常
  2. 类、接口和类型定义
  3. 访问级别和可见性
  4. 代码元素之间的关系
  5. 事件和回调
  6. 示例和教程

良好的文档不仅有助于其他开发者理解代码,也有助于集成开发环境(IDE)提供更好的代码补全和类型检查。在大型项目中,投入时间编写详细的 JSDoc 注释是非常值得的。

速查表

下表提供了常用 JSDoc 标签的简明参考,便于快速查找和使用。

描述性标签

标签说明示例
@description提供详细描述@description 计算两个数字的和
@summary提供简短概述@summary 简单求和函数
@example提供使用示例@example add(1, 2); // 返回 3
@since指明功能起始版本@since 1.0.0
@deprecated标记已废弃功能@deprecated 使用 sum() 代替
@todo标记待完成工作@todo 添加输入验证
@author指定作者@author 张三 <zhangsan@example.com>
@version指定版本@version 1.0.0
@copyright提供版权信息@copyright 2025 Example Corp.
@license提供许可证信息@license MIT

类相关标签

标签说明示例
@class标记构造函数@class
@classdesc提供类描述@classdesc 表示一个人的类
@constructor标记构造函数@constructor
@hideconstructor隐藏构造函数@hideconstructor
@constructs标记创建对象的函数@constructs
@instance标记类实例@instance
@interface标记接口@interface

函数相关标签

标签说明示例
@function标记函数@function
@method标记方法@method
@param描述参数@param {number} a - 第一个数字
@argument@param 的别名@argument {number} a - 第一个数字
@returns描述返回值@returns {number} 两个数字的和
@throws描述可能的异常@throws {Error} 当除数为 0 时
@async标记异步函数@async
@generator标记生成器函数@generator
@yields描述生成器 yield 值@yields {number} 连续的数字
@callback描述回调函数类型@callback resultCallback
@overload标记函数重载@overload

模块和命名空间

标签说明示例
@module标记模块@module math-utils
@exports标记模块导出@exports
@namespace标记命名空间@namespace
@memberof标记所属父符号@memberof MathUtils
@requires标记依赖@requires axios

类型标签

标签说明示例
@type指定变量类型@type {number}
@typedef定义自定义类型@typedef {Object} User
@template定义泛型参数@template T
@var标记变量@var {number}
@constant标记常量@constant {number}
@default指定默认值@default options={}
@property描述对象属性@property {string} name - 用户名
@prop@property 的别名@prop {string} name - 用户名

继承和关系标签

标签说明示例
@extends标记类继承@extends Animal
@augments@extends 的别名@augments Animal
@implements标记接口实现@implements Comparable
@mixes标记混入@mixes LoggerMixin
@inheritdoc继承文档@inheritdoc
@lends指定属性归属@lends Person.prototype
@borrows借用文档@borrows Formatter.formatDate as format

访问控制标签

标签说明示例
@public标记公开成员@public
@private标记私有成员@private
@protected标记受保护成员@protected
@access指定访问级别@access private
@readonly标记只读成员@readonly
@package标记包级别可见性@package

其他标签

标签说明示例
@abstract标记抽象方法@abstract
@alias提供别名@alias MathUtils.add
@event描述事件@event User#login
@emits标记发出的事件@emits User#login
@fires@emits 的别名@fires UserService#userCreated
@listens标记监听的事件@listens UserService#userCreated
@file提供文件描述@file 数学工具库
@fileoverview@file 的别名@fileoverview 用户管理模块
@this描述 this 含义@this {TaskRunner}
@global标记全局成员@global
@link创建文档链接@see {@link UserService}
@linkcode创建代码链接@see {@linkcode DateUtils.format}
@linkplain创建纯文本链接@see {@linkplain Auth.validateUser}
@see引用其他文档@see subtract 相反操作
@tutorial引用教程@tutorial user-authentication
@external标记外部类/命名空间@external jQuery
@host指定主机对象@host MyLibrary
@inner标记内部成员@inner
@satisfies标记类型满足接口@satisfies {Comparable}
@kind指定元素类型@kind class
@name指定元素名称@name add
@field标记类字段@field
@static标记静态成员@static
@variation标记变体@variation 2
@virtual标记可被重写的方法@virtual

官方文档

官方文档:JSDoc Documentation