Awesome article about JSDoc. I learned (er remembered) a few things from reading it myself! via @rauschma 2ality.com/2011/08/jsdoc-intro.html
As a tool, JSDoc takes JavaScript code with special /** */ comments and produces HTML documentation for it. For example: Given the following code.
/** @namespace */ var util = { /** * Repeat <tt>str</tt> several times. * @param {string} str The string to repeat. * @param {number} [times=1] How many times to repeat the string. * @returns {string} */ repeat: function(str, times) { if (times === undefined || times < 1) { times = 1; } return new Array(times+1).join(str); } };The generated HTML looks as follows in a web browser:
JSDOCDIR="$HOME/local/jsdoc-toolkit" JSDOCTEMPLATEDIR="$JSDOCDIR/templates/jsdoc"Now you can move the script anywhere you want to, e.g. a bin/ directory. For the purpose of this demonstration, we don’t move the script.
$HOME/jsdoc-toolkit/jsrun.sh -d=$HOME/doc $HOME/js
$HOME/doc ├── files.html ├── index.html └── symbols ├── _global_.html ├── src │ └── util.js.html └── util.html
Templates. In order to output anything, JSDoc always needs a template, a mix of JavaScript and specially marked-up HTML that tells it how to translate the parsed documentation to HTML. JSDoc comes with a built-in template, but there are others that you can download [3].
function MyClass() { var privateCounter = 0; // an inner member this.inc = function() { // an instance property privateCounter++; }; }
/** * Repeat <tt>str</tt> several times. * @param {string} str The string to repeat. * @param {number} [times=1] How many times to repeat the string. * @returns {string} */This demonstrates some of the JSDoc syntax which consists of the following pieces.
Single type: @param {string} name Multiple types: @param {string|number} idCode Arrays of a type: @param {string[]} names
myFunction MyConstructor MyConstructor.classProperty MyConstructor#instanceProperty MyConstructor-innerMember
> typeof "" 'string'Compare: an instance of the wrapper type is an object.
> typeof new String() 'object'
> new String().constructor.name 'String'
/** * @fileOverview Various tool functions. * @author <a href="mailto:jd@example.com">John Doe</a> * @version 3.1.2 */
/** * @example * var str = "abc"; * console.log(repeat(str, 3)); // abcabcabc */
/** * @see MyClass#myInstanceMethod * @see The <a href="http://example.com">Example Project</a>. */
@version 10.3.1
@since 10.2.0
@param str @param str The string to repeat. @param {string} str @param {string} str The string to repeat.Advanced features:
@param {number} [times] The number of times is optional.
@param {number} [times=1] The number of times is optional.
/** * @param {String} name * @returns {Object} */ function getPerson(name) { }Second, you can inline the type information:
function getPerson(/**String*/ name) /**Object*/ { }
/** @constructor */ function Car(make, owner) { /** @type {string} */ this.make = make; /** @type {Person} */ this.owner = owner; } @type {Person}This tag can also be used to document the return type of functions, but @returns is preferable in this case.
/** @constructor */ function Page(title) { /** * @default "Untitled" */ this.title = title || "Untitled"; }
/** * @class * @property {string} name The name of the person. */ function Person(name) { this.name = name; }Without this tag, instance properties are documented as follows.
/** * @class */ function Person(name) { /** * The name of the person. * @type {string} */ this.name = name; }Which one of those styles to use is a matter of taste. @property does introduce redundancies, though.
/** * @constructor */ function Person(name) { }@class is a synonym for @constructor, but it also allows you to describe the class – as opposed to the function setting up an instance (see tag documentation below for an example).
/** @class */ var Person = makeClass( /** @lends Person# */ { say: function(message) { return "This person says: " + message; } } );
var Person = makeClass( /** @lends Person# */ { /** * A class for managing persons. * @constructs */ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + " says: " + message; } } );
/** * Creates a new instance of class Person. * @class Represents a person. */ Person = function() { }
/** * @constructor * @extends Person */ function Programmer(name) { Person.call(this, name); ... } // Remaining code for subclassing omitted
/** @namespace */ var util = { ... };
/**#@+ * @private * @memberOf Foo */ function baz() {} function zop() {} function pez() {} /**#@-*/
/** * @constructor * @borrows Remote#transfer as this.send */ function SpecialWriter() { this.send = Remote.prototype.transfer; }
Name and membership:
Tag Mark variable as @function function @field non-function value @public public (especially inner variables) @private private @inner inner and thus also private @static accessible without instantiation