Best way to document anonymous objects and functions with jsdoc

65,165

Solution 1

You can document stuff that doesnt exist in the code by using the @name tag.

/**
 * Description of the function
 * @name IDontReallyExist
 * @function
 * @param {String} someParameter Description
*/

/**
 * The CallAgain method calls the provided function twice
 * @param {IDontReallyExist} func The function to call twice
*/
exports.CallAgain = function(func) { func(); func(); }

Here is the @name tag documentation. You might find name paths useful too.

Solution 2

You can use @callback or @typedef.

/**
 * @callback arrayCallback
 * @param  {object} element - Value of array element
 * @param  {number} index   - Index of array element
 * @param  {Array}  array   - Array itself
 */

/**
 * @param {arrayCallback} callback - function applied against elements
 * @return {Array} with elements transformed by callback
 */
Array.prototype.map = function(callback) { ... }

Solution 3

To compliment studgeek's answer, I've provided an example that shows what JsDoc with Google Closure Compiler lets you do.

Note that the documented anonymous types get removed from the generated minified file and the compiler ensures valid objects are passed in (when possible). However, even if you don't use the compiler, it can help the next developer and tools like WebStorm (IntelliJ) understand it and give you code completion.

// This defines an named type that you don't need much besides its name in the code
// Look at the definition of Page#getPage which illustrates defining a type inline
/**  @typedef { pageId : string, pageName : string, contents: string} */
var PageResponse;

/**
 * @class {Page} Page Class specification
 */
var Page = function() {    
    /**
     * Get a page from the server
     * @param {PageRequest} pageRequest Info on the page you want to request
     *
     * The type for the second parameter for the function below is defined inline
     *
     * @param {function(PageResponse, {statusCode: number, statusMsg: string})} callback
     *        Function executed when page is retrieved
     */
    this.getPage = function(pageRequest, callback) {
    }; 
};

Solution 4

@link can add inline links to methods and classes.

/**
 * Get a page from the server
 * @param {PageRequest} pageRequest Info on the page you want to request
 * @param {function} callback Function executed when page is retrieved<br />
 * function({@link PageResponse} pageResponse,{@link PageRequestStatus} pageRequestStatus)
 */
this.getPage = function (pageRequest, callback) {
};

Not ideal, but it gets the job done.

Solution 5

The Google Closure Compiler Annotations has Type Expressions for this which includes the ability to indicate type for specific arguments, return type, and even this. Many libraries are looking at following the Google Closure Compiler Annotations, because they want to use it to shrink their code. So it's got some momentum. The downside is I don't see a way to give the description.

For providing the description perhaps the JSDoc Toolkit Parameters With Properties approach would work (look at the bottom of the page). It's what I am doing right now. The JSDoc Toolkit is prepping to start work on V3, so feedback there might be good.

Share:
65,165
Josh Johnson
Author by

Josh Johnson

I do software development.

Updated on July 05, 2022

Comments

  • Josh Johnson
    Josh Johnson almost 2 years

    Edit: This is technically a 2 part question. I've chosen the best answer that covers the question in general and linked to the answer that handles the specific question.

    What is the best way to document anonymous objects and functions with jsdoc?

    /**
     * @class {Page} Page Class specification
     */
    var Page = function() {
    
        /**
         * Get a page from the server
         * @param {PageRequest} pageRequest Info on the page you want to request
         * @param {function} callback Function executed when page is retrieved
         */
        this.getPage = function(pageRequest, callback) {
        }; 
    };
    

    Neither the PageRequest object or the callback exist in code. They will be provided to getPage() at runtime. But I would like to be able to define what the object and function are.

    I can get away with creating the PageRequest object to document that:

    /**
     * @namespace {PageRequest} Object specification
     * @property {String} pageId ID of the page you want.
     * @property {String} pageName Name of the page you want.
     */
    var PageRequest = {
        pageId : null,
        pageName : null
    };
    

    And that's fine (though I'm open to better ways to do this).

    What is the best way to document the callback function? I want to make it know in the document that, for example, the callback function is in the form of:

    callback: function({PageResponse} pageResponse, {PageRequestStatus} pageRequestStatus)
    

    Any ideas how to do this?

  • Josh Johnson
    Josh Johnson almost 14 years
    Thanks, no. I'm doing that currently (without the ifdef) and it works, but I'd like for the user to be able to see immediately that it's a function that accepts params X and Y without leaving where they're at. Similar to how the google map api does it. example: code.google.com/apis/maps/documentation/javascript/…
  • Josh Johnson
    Josh Johnson almost 14 years
    Just found out that @link can do what I'm talking about. It's not perfect but it works. I'll create a separate answer in case anyone else finds it useful.
  • oligofren
    oligofren about 11 years
    Really neat! A great way to document callbacks.
  • oligofren
    oligofren about 11 years
    But I don't see how this works for anonymous objects? Say a settings object that is sent into some function to create an object which is not visible in the current scope.
  • Eric
    Eric about 11 years
    If you don't want to use the @name tag to give a name to your anonymous object, describe the object where its used, that would be the @param tag's body for your settings object example.
  • kzh
    kzh almost 11 years
    There is also the @callback tag.
  • kzh
    kzh almost 10 years
    @ChrisMoschini Thanks. The @callback tag in the answer was linked to the appropriate documentation page.
  • נשמה קשוחה
    נשמה קשוחה almost 8 years
    Hi, this seems the most elegant answer, however JSDoc output just contains function without the specific parameter typing. I am using jsdoc 3.4.0. Is this syntax not fully supported?
  • Ruan Mendes
    Ruan Mendes almost 8 years
    @PeteV. I haven't kept up with the level of synchronization between jsdoc and closure compiler. I would recommend you look at alternative doc generators that are made to work with closure compiler (since it's a superset of the jsdoc standard). Try plovr.com , seehuhn.de/pages/jvjsdoc or github.com/google/closure-compiler/wiki/… . I have moved on to using TypeScript for adding static typing to JavaScript