Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can JSDoc document dynamically generated methods?

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.

like image 204
kdbanman Avatar asked Mar 16 '16 16:03

kdbanman


People also ask

What is JSDoc used for?

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.

Why is JSDoc important?

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.

How to create JSDoc comment?

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.

How to write Js docs?

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.


2 Answers

@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.
     */
}
like image 110
Peter Avatar answered Oct 13 '22 01:10

Peter


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.

like image 28
kdbanman Avatar answered Oct 12 '22 23:10

kdbanman