Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSDoc - how to document prototype methods

I've been trying to document the following code using JSDoc:

/**
 * @module person
 */

 /**
  * A human being.
  * @class
  * @param {string} name
  */
function Person(name){
    this.name = name
}

Person.prototype = new function(){
    var amount_of_limbs = 4;

    /**
     * Introduce yourself
     */
    this.greet = function(){
        alert("Hello, my name is " + this.name + " and I have " + amount_of_limbs + " limbs");
    }
}

But the method greet is nowhere to be found in the resulting JSDoc documentation. What am I doing wrong?

like image 309
Kuba Orlik Avatar asked Dec 07 '14 13:12

Kuba Orlik


3 Answers

Don't add prototype members like that. That's weird / bad / wrong.

You're setting the whole prototype of an existing object, rather than adding members to it. This will lead to performance problems, JS engine optimising issues and unexpected behaviour.

If you somehow need to overwrite the prototype, you should use Object.setPrototypeOf() method. Which is still not recommended even though it's a native method.

If your only problem is to "hide" some private constant, you have these options:

  1. Use an IIFE (Immediately Invoked Function Expression):
/**
 * A human being.
 * @class
 */
var Person = (function () {

    // private variables
    var amountOfLimbs = 4;

    /**
     * Initializes a new instance of Person.
     * @constructs Person
     * @param {string} name
     */
    function Person(name) {
        /**
         * Name of the person.
         * @name Person#name
         * @type {String}
         */
        this.name = name
    }

    /**
     * Introduce yourself
     * @name Person#greet
     * @function
     */
    Person.prototype.greet = function () {
        alert("Hello, my name is " + this.name + " and I have " + amountOfLimbs + " limbs");
    };

    return Person;
})();
  1. Use the conventional _ prefix for private vars/constants and use JSDoc @private tag.
/**
 * Person class.
 * @class
 */
function Person(name) {

    /**
     * Name of the person.
     * @name Person#name
     * @type {String}
     */
    this.name = name

    /**
     * Amount of limbs.
     * @private
     */
    this._amountOfLimbs = 4;
}

/**
 * Introduce yourself.
 * @name Person#greet
 * @function
 */
Person.prototype.greet = function () {
    alert("Hello, my name is " + this.name + " and I have " + this._amountOfLimbs + " limbs");
};
like image 188
Onur Yıldırım Avatar answered Oct 17 '22 04:10

Onur Yıldırım


According to https://github.com/jsdoc3/jsdoc/issues/596 the correct answer would be: use @memberof

 /**
  * A human being.
  * @class
  * @constructor
  * @param {string} name
  */
function Person(name) { /*...*/ }
Person.prototype = {};
Person.prototype.constructor = Person;

/**
 * Perform a greeting.
 * @memberof Person
 */
Person.prototype.greet = function () { /*...*/ }
like image 43
floww Avatar answered Oct 17 '22 04:10

floww


You can use @lends.

(function() {
    var amount_of_limbs = 4;

    MyClass.prototype = /** @lends MyClass# */ {
        /**
         * Introduce yourself
         */
        greet: function(){
            alert("Hello, my name is " + this.name + " and I have " + amount_of_limbs + " limbs");
        }
    };
})();

It is a slightly modified version. But the result is the same. You have a separate scope for a prototype.

From here.

like image 2
FreeLightman Avatar answered Oct 17 '22 04:10

FreeLightman