JSDoc 是一种用于 JavaScript 的文档生成工具,它通过特殊的注释来描述代码的功能、参数、返回值等信息。这些注释可以帮助开发者更好地理解和维护代码,同时也可以生成详细的 API 文档。以下是一些常用的 JSDoc 注解及其示例:
基本注解
- @param: 描述函数的参数。
- @returns: 描述函数的返回值。
- @description: 描述函数或类的用途。
- @example: 提供使用示例。
- @typedef: 定义类型别名。
- @property: 描述对象的属性。
- @class: 描述类。
- @constructor: 描述类的构造函数。
- @method: 描述类的方法。
- @memberof: 指定成员属于哪个类或对象。
- @fires: 描述触发的事件。
- @see: 提供参考链接或相关方法。
- @deprecated: 标记已弃用的函数或类。
- @throws: 描述抛出的异常。
示例
函数注解
javascript
/**
* 计算两个数的和。
* @param {number} a - 第一个加数。
* @param {number} b - 第二个加数。
* @returns {number} 两个数的和。
* @example
* const result = add(2, 3); // 返回 5
*/
function add(a, b) {
return a + b;
}
函数参数是对象类型
假设你有一个函数 createUser
,它接受一个对象作为参数,该对象包含 name
和 age
属性。
javascript
/**
* 创建一个用户对象。
* @param {Object} user - 用户对象。
* @param {string} user.name - 用户的名字。
* @param {number} user.age - 用户的年龄。
* @returns {Object} - 创建的用户对象。
*/
function createUser(user) {
return {
name: user.name,
age: user.age
};
}
// 使用示例
const user = createUser({ name: 'Alice', age: 30 });
console.log(user); // { name: 'Alice', age: 30 }
使用 @typedef
定义复杂对象类型
对于更复杂的对象类型,你可以使用 @typedef
注解来定义一个类型别名,然后在 @param
注解中引用这个类型别名。
javascript
/**
* @typedef {Object} User
* @property {string} name - 用户的名字。
* @property {number} age - 用户的年龄。
* @property {string[]} [hobbies] - 用户的兴趣爱好(可选)。
*/
/**
* 创建一个用户对象。
* @param {User} user - 用户对象。
* @returns {User} - 创建的用户对象。
*/
function createUser(user) {
return {
name: user.name,
age: user.age,
hobbies: user.hobbies || []
};
}
// 使用示例
const user = createUser({ name: 'Bob', age: 25, hobbies: ['reading', 'coding'] });
console.log(user); // { name: 'Bob', age: 25, hobbies: ['reading', 'coding'] }
嵌套对象类型
如果你需要描述嵌套的对象类型,可以在 @param
注解中直接定义嵌套的属性。
javascript
/**
* 创建一个用户对象。
* @param {Object} user - 用户对象。
* @param {string} user.name - 用户的名字。
* @param {number} user.age - 用户的年龄。
* @param {Object} user.address - 用户的地址。
* @param {string} user.address.street - 街道名称。
* @param {string} user.address.city - 城市名称。
* @param {string} user.address.country - 国家名称。
* @returns {Object} - 创建的用户对象。
*/
function createUser(user) {
return {
name: user.name,
age: user.age,
address: {
street: user.address.street,
city: user.address.city,
country: user.address.country
}
};
}
// 使用示例
const user = createUser({
name: 'Charlie',
age: 35,
address: {
street: '123 Main St',
city: 'Anytown',
country: 'USA'
}
});
console.log(user); // { name: 'Charlie', age: 35, address: { street: '123 Main St', city: 'Anytown', country: 'USA' } }
使用 @param
注解的简化形式
你也可以在 @param
注解中直接使用对象字面量来描述复杂的对象类型。
javascript
/**
* 创建一个用户对象。
* @param {{ name: string, age: number, address: { street: string, city: string, country: string } }} user - 用户对象。
* @returns {Object} - 创建的用户对象。
*/
function createUser(user) {
return {
name: user.name,
age: user.age,
address: {
street: user.address.street,
city: user.address.city,
country: user.address.country
}
};
}
// 使用示例
const user = createUser({
name: 'David',
age: 40,
address: {
street: '456 Elm St',
city: 'Othertown',
country: 'Canada'
}
});
console.log(user); // { name: 'David', age: 40, address: { street: '456 Elm St', city: 'Othertown', country: 'Canada' } }
总结
通过使用 JSDoc 的 @param
注解,你可以详细描述函数参数的对象类型,包括对象的属性及其类型。对于复杂的对象类型,可以使用 @typedef
注解来定义类型别名,使代码更加清晰和易于维护。这些注解不仅有助于其他开发者理解你的代码,还可以生成详细的 API 文档。
函数参数是多种类型
在 JSDoc 中,如果你的函数参数可以是多种类型之一,可以使用联合类型(Union Types)来表示。联合类型允许你指定一个参数可以是几种不同类型的任意一种。以下是如何为一个可能为字符串、函数或 null
的参数进行注解的示例:
假设你有一个函数 processInput
,它的第一个参数 input
可以是字符串、函数或 null
。
javascript
/**
* 处理输入值。
* @param {(string|Function|null)} input - 输入值,可以是字符串、函数或 null。
* @returns {string} - 处理后的结果。
*/
function processInput(input) {
if (typeof input === 'string') {
return `String input: ${input}`;
} else if (typeof input === 'function') {
return `Function input: ${input()}`;
} else if (input === null) {
return 'Null input';
} else {
throw new Error('Invalid input type');
}
}
// 使用示例
console.log(processInput('hello')); // 输出: String input: hello
console.log(processInput(() => 'world')); // 输出: Function input: world
console.log(processInput(null)); // 输出: Null input
解释
(string|Function|null)
: 这是一个联合类型,表示input
参数可以是string
、Function
或null
中的任意一种。@param {(string|Function|null)} input
: 这个注解指定了input
参数的类型可以是string
、Function
或null
。
类注解
javascript
/**
* 一个表示用户的类。
*/
class User {
/**
* 创建一个新的用户实例。
* @param {string} name - 用户的名字。
* @param {number} age - 用户的年龄。
*/
constructor(name, age) {
this.name = name;
this.age = age;
}
/**
* 获取用户的介绍。
* @returns {string} 用户的介绍信息。
*/
getIntroduction() {
return `My name is ${this.name} and I am ${this.age} years old.`;
}
}
类型别名
javascript
/**
* 定义一个用户对象的类型。
* @typedef {Object} User
* @property {string} name - 用户的名字。
* @property {number} age - 用户的年龄。
*/
/**
* 创建一个用户对象。
* @param {string} name - 用户的名字。
* @param {number} age - 用户的年龄。
* @returns {User} 用户对象。
*/
function createUser(name, age) {
return {
name,
age
};
}
事件注解
javascript
/**
* 触发登录成功的事件。
* @event loginSuccess
* @param {string} username - 登录的用户名。
*/
/**
* 模拟登录过程。
* @fires loginSuccess
*/
function login(username) {
// 模拟登录过程
console.log(`${username} logged in successfully.`);
// 触发登录成功事件
document.dispatchEvent(new CustomEvent('loginSuccess', { detail: { username } }));
}
弃用注解
javascript
/**
* 获取用户的年龄(已弃用,请使用 getUserAge 代替)。
* @param {User} user - 用户对象。
* @returns {number} 用户的年龄。
* @deprecated
*/
function getUserAgeDeprecated(user) {
return user.age;
}
/**
* 获取用户的年龄。
* @param {User} user - 用户对象。
* @returns {number} 用户的年龄。
*/
function getUserAge(user) {
return user.age;
}
生成文档
使用 JSDoc 工具可以生成 HTML 格式的文档。安装 JSDoc 可以通过 npm:
javascript
npm install -g jsdoc
生成文档的命令:
javascript
jsdoc yourfile.js -d docs
这会在 docs
目录下生成 HTML 文档。
类型名称规则
在 JSDoc 中,类型名称的首字母是否大写取决于类型的具体含义和来源。以下是详细的解释:
基本类型
基本类型(如 string
、number
、boolean
、null
、undefined
)是 JavaScript 的内置类型,这些类型名称在 JSDoc 中通常使用小写字母。这是因为这些类型是语言级别的关键字,而不是自定义的类或构造函数。
javascript
/**
* @param {string} name - 用户的名字。
* @param {number} age - 用户的年龄。
*/
function createUser(name, age) {
// ...
}
对象类型
对象类型通常是指自定义的类型或类。在 JSDoc 中,自定义的类型或类的名称通常使用大写字母开头,以区分它们与基本类型。这样做可以更清楚地表明这些类型是由用户定义的,而不是语言内置的类型。
javascript
/**
* @typedef {Object} User
* @property {string} name - 用户的名字。
* @property {number} age - 用户的年龄。
*/
/**
* @param {User} user - 用户对象。
*/
function createUser(user) {
// ...
}
类型别名
当你使用 @typedef
注解定义一个类型别名时,这个别名通常也会使用大写字母开头,以表明它是一个自定义类型。
javascript
/**
* @typedef {Object} Address
* @property {string} street - 街道名称。
* @property {string} city - 城市名称。
* @property {string} country - 国家名称。
*/
/**
* @typedef {Object} User
* @property {string} name - 用户的名字。
* @property {number} age - 用户的年龄。
* @property {Address} address - 用户的地址。
*/
/**
* @param {User} user - 用户对象。
*/
function createUser(user) {
// ...
}
内置对象类型
某些内置对象类型(如 Array
、Date
、RegExp
等)也是大写字母开头,因为它们是构造函数,可以通过 new
关键字创建实例。
javascript
/**
* @param {Array<string>} names - 用户的名字列表。
*/
function printNames(names) {
// ...
}
/**
* @param {Date} date - 日期对象。
*/
function formatDate(date) {
// ...
}
总结
- 小写字母开头 :用于表示基本类型(如
string
、number
、boolean
、null
、undefined
)。 - 大写字母开头 :用于表示自定义类型、类、构造函数以及某些内置对象类型(如
Array
、Date
、RegExp
)。
这种命名约定有助于区分不同类型,使代码更具可读性和一致性。