Here is a constructor function A
that gives instances 2 methods: printThing
and printBall
. I use JSDoc to document methods like this:
var A = function () {
/**
* Prints 'Thing'
* @param {Number} N - The number of times to print.
*/
this.printThing = function (N) {
var i = 0;
while (i < N) {
console.log('Thing');
i++
}
};
/**
* Prints 'Ball'
* @param {Number} N - The number of times to print.
*/
this.printBall = function (N) {
var i = 0;
while (i < N) {
console.log('Ball');
i++
}
};
};
Here is an equivalent constructor function that dynamically generates the same methods like this:
var A = function () {
var me = this;
var registerPrinter = function (name) {
me['print' + name] = function (N) {
var i = 0;
while (i < N) {
console.log(name);
i++;
}
};
};
registerPrinter('Thing');
registerPrinter('Ball');
}
The behaviour of the instances generated by the two constructor functions are identical:
> var a = new A();
> a.printBall(4);
Ball
Ball
Ball
Ball
How can I use JSDoc to document the generated methods in the second A
constructor function?
EDIT: registerPrinter
is private within the scope of the constructor function. It can (and should) be documented, but it's just used internally. This question is about documenting the resulting public interface of A
instances.
JSDoc is a markup language used to annotate JavaScript source code files. Using comments containing JSDoc, programmers can add documentation describing the application programming interface of the code they're creating.
JSDoc's purpose is to document the API of your JavaScript application or library. It is assumed that you will want to document things like modules, namespaces, classes, methods, method parameters, and so on. JSDoc comments should generally be placed immediately before the code being documented.
Create JSDoc commentsPosition the caret before the declaration of the method/function or field to document, type the opening block comment /** , and press Enter . WebStorm generates a JSDoc comment with a list of parameters ( @param ) and return values ( @returns ), where applicable.
Documenting data types JavaScript has various data types like strings, numbers, arrays, and objects. The snippets below show how to document each of them using JSDocs. /** * Documentaion for a string * Article Name * @type {string} */ const articleName = "Javascript Documentation"; Number.
@name
is made for this:
This tag is best used in "virtual comments" for symbols that are not readily visible in the code...
ES6:
/** Class A */
class A {
constructor () {
['Thing', 'Ball'].map((name) => {
this['print' + name] = (N) => {
let i = 0;
while (i < N) {
console.log(name);
i++;
}
};
});
}
}
/**
* @name A#printThing
* @function
* @memberof A
* @description Prints 'Thing'
* @param {Number} N - The number of times to print.
*/
/**
* @name A#printBall
* @function
* @memberof A
* @description Prints 'Ball'
* @param {Number} N - The number of times to print.
*/
ES5:
/**
* @class A
*/
var A = function () {
var me = this;
var registerPrinter = function (name) {
me['print' + name] = function (N) {
var i = 0;
while (i < N) {
console.log(name);
i++;
}
};
};
['Thing', 'Ball'].map(registerPrinter);
/**
* @name A#printThing
* @function
* @memberof A
* @description Prints 'Thing'
* @param {Number} N - The number of times to print.
*/
/**
* @name A#printBall
* @function
* @memberof A
* @description Prints 'Ball'
* @param {Number} N - The number of times to print.
*/
}
After a day of trawling the docs, this is the best option I can find. It requires a slightly different equivalent definition of A
, and a change to registerPrinter
. It's slightly more verbose, but the maintainability benefits of not repeating very similar methods are preserved, and it's more readable:
var A = function () {
var generatePrinter = function (name) {
return function (N) {
var i = 0;
while (i < N) {
console.log(name);
i++;
}
};
};
/**
* Prints 'Thing'
* @param {Number} N - The number of times to print.
*/
this.printThing = generatePrinter('Thing');
/**
* Prints 'Ball'
* @param {Number} N - The number of times to print.
*/
this.printBall = generatePrinter('Ball');
}
Note that this is no longer dynamically adding the properties printThing
or printBall
to this
(though the methods are still dynamically generated). Hence, this isn't a direct solution to the question - it's a work around. I will accept any future answer that actually documents dynamically added properties.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With