Documentation.js 项目中的代码文档编写指南
前言
Documentation.js 是一个强大的 JavaScript 文档生成工具,它能够从代码注释中自动生成美观且结构化的文档。本文将深入探讨如何为不同 JavaScript 特性编写规范的文档注释,帮助开发者充分利用 Documentation.js 的功能。
ES6 类的文档编写
ES6 类语法为 JavaScript 带来了正式的类定义方式,Documentation.js 对此有很好的支持。
最佳实践
关键原则:类的构造函数参数应该直接在类注释中声明,而不是在 constructor 方法中。
正确示例:
/**
* 表示一个表格对象
* @param {number} width 表格宽度
* @param {number} height 表格高度
*/
class Table {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
错误示例:
/** 表示一个表格对象 */
class Table {
/*
* @param {number} width 表格宽度
* @param {number} height 表格高度
*/
constructor(width, height) {
this.width = width;
this.height = height;
}
}
原因分析:将参数文档放在类级别注释中更符合逻辑,因为构造函数的参数实际上是类的实例化参数,而不是构造函数方法本身的参数。
类工厂模式的文档编写
许多库和框架(如 Dojo、React、Ext 等)使用特殊的"类构造器方法"来创建类。这些方法通常接收一个对象作为输入,并返回一个类,该对象的属性将成为类的原型属性。
使用 @lends 标签
Documentation.js 无法自动识别这些模式,但可以通过 @lends
标签显式指示。
示例:
/**
* 这是 SelectionEngine 类的文档说明
*/
const SelectionEngine = declare(
null,
/** @lends SelectionEngine */ {
/**
* 此方法将被解析为 SelectionEngine.expandColsTo
* 因为包含它的对象使用了 @lends 标签,
* 表明它将被混入 SelectionEngine 的原型中。
*/
expandColsTo: function(foo, bar, baz) {}
}
);
工作原理:
- 当你使用辅助函数创建类时
- 并且你提供了一个包含属性的对象作为参数之一
- 在该对象前添加
/** @lends ClassName */
标签 - 对象中的属性将被正确分配到类的原型上
解构参数的文档编写
ES6 允许在函数参数中使用解构赋值,这使得我们可以轻松编写只使用对象部分属性的函数。
解构参数的命名问题
解构参数在代码中是"未命名"的 - 虽然我们有 x 和 y 的名称,但函数没有声明调用时传入的对象名称。因此,在 Documentation.js 中必须为解构参数指定父对象名称。
正确示例:
/**
* 此方法具有分层参数
* @param {Object} animals 不同种类的动物
* @param {String} animals.fishes 鱼类数量
*/
function fishesAndFoxes({ fishes, foxes }) {
return fishes + foxes;
}
注意事项:从 Documentation.js 4.0.0-rc.1 开始,必须使用这种显式语法,不再支持隐式命名(如 $0
, $1
等)。
对象工厂模式的文档编写
像 d3 这样的库倾向于使用"对象工厂"或"模块模式"而不是 JavaScript 的 new
操作符。
工厂函数文档
工厂函数是返回对象的普通函数。这种情况下我们不使用 @class
标签,因为我们不使用 new
操作符或修改任何对象的 prototype
。
示例:
/**
* 面积图生成器
* @returns {chart} 图表对象
*/
var area = function() {
/**
* 在给定的选择上运行图表
* @param {Selection} selection 选择器
*/
var chart = function(selection) {
};
/**
* 设置图表数据
*/
chart.data = function(_) {
};
return chart;
};
重载方法的文档编写
在 jQuery、d3 等简洁的 JavaScript 库中常见的是 getter-setter 方法,即同一个方法既可以获取值也可以设置值。
最佳实践
推荐方式:为这两种用法分别编写文档注释。
示例:
var theTime;
/**
* 获取当前时间
* @returns {Date} 当前日期
*/
/**
* 设置当前时间
* @param {Date} time 要设置的时间
* @returns {undefined} 无返回值
*/
function getTheTime(time) {
if (arguments.length === 0) {
return new Date();
} else {
theTime = time;
}
}
效果:Documentation.js 会输出两个独立的函数文档,分别描述无参数调用和有参数调用的情况。
Promise 的文档编写
Promise 已成为现代 JavaScript 中广泛使用的特性,其文档编写方式与数组类似。
示例:
/**
* 在数据库中查找某人的电话号码
* @param {string} name 人名
* @returns {Promise<string>} 包含电话号码的 Promise
*/
function findPersonAge(name) {
return new Promise((resolve, reject) => {
db.find({ name: name })
.then(object => resolve(object.age))
.catch(err => reject(err))
})
}
多参数情况:可以使用 Promise<string, number>
这样的格式来文档化 resolve 中的多个参数。
总结
通过遵循这些规范,开发者可以充分利用 Documentation.js 的强大功能,为各种 JavaScript 特性生成清晰、准确的文档。无论是传统的类定义、现代的 ES6 特性,还是各种设计模式,都有相应的文档注释方法。掌握这些技巧将显著提升代码的可维护性和可读性。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考