JSDoc - how to document prototype methods
Asked Answered
C

5

24

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?

Cubiform answered 7/12, 2014 at 13:33 Comment(3)
Did you find a solution?Sanctimonious
I think I have. It involved using @alias AFAIR. usejsdoc.org/tags-alias.htmlCubiform
Oops, you did mention that in answer, somehow I missed that. Too bad you didn't elaborate your answer to demonstrate it with the example from your question. All the same, thanks for following up.Sanctimonious
K
11

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");
};
Knutson answered 15/5, 2016 at 22:54 Comment(6)
Could you explain why that approach is wrong? In my example the amount_of_limbs variable is private to the prototype. Can you show us how can we achieve that in your approach?Cubiform
@Onur Yıldırım Although your answer is a very interesting comment, it does not answer the OP question, which is "how to document prototype methods?" If you have the answer to this question, please update your answer. I would be curious to know what the solution is.Gurevich
@Jean-FrançoisBeauchamp thanks but this also shows how to document. Still, improved a bit.Budd
@Onur Yıldırım I tried to run jsDoc 3 on your sample code and the Perspn class gets documented, but not the greet prototype method. Are you getting a different result?Gurevich
@Onur Yıldırım Teşekkür ederim!Gurevich
@Jean-FrançoisBeauchamp De rien :)Budd
N
5

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 () { /*...*/ }
Neonate answered 5/3, 2017 at 16:31 Comment(0)
T
2

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.

Tonie answered 26/2, 2018 at 21:47 Comment(0)
M
0

For prototypes I think you're just looking for @inheritdoc - http://usejsdoc.org/tags-inheritdoc.html or @augments/@extends - http://usejsdoc.org/tags-augments.html

I'm not sure that Onur's example is the correct use of prototypes. from my understanding the example creates a new instance of the prototype each time rather than linking to the same one so you don't really benefit in using them. If you're looking for code to function in that mannor a straight up factory or construcor function will do the job really well.

Perosnally I like the constructor approach as shown below, you may like the factory functions syntax better though and it probably gets more attention these days.

/**
 * A human being.
 * @constructor
 */
var person = function(name){
    // private variables
    var amount_of_limbs = 4;
    // public members
    this.name = name;

    /**
     * Introduce yourself
     */
    this.greet = function () {
        console.log("name is: "+this.name+" I have "+amount_of_limbs+" limbs"); 
    }.bind(this);

    return this;
};


var me = person.call({},'Michael');
me.greet(); //"name is: Michael I have 4 limbs"/

var you = person.call({},'Kuba');
you.greet(); //"name is: Kuba I have 4 limbs"/

Lastly; I don't think I could comment here without mentioning Kyle Simpsons OLOO pattern. It's a prototype delegation pattern which you may prefer to traditional prototypal syntax. There's more in his "You don't know JS" series and blog.

Mislay answered 9/6, 2016 at 3:24 Comment(3)
gist.github.com/getify/5572383#file-ex2-oloo-style-js-L4 < gist comparing OLOO to traditional prototypes.Mislay
"I'm not sure that Onur's example is the correct use of prototypes." Yes, it totally is. wel lencapsulated, but still is. On the other hand your example is not using protptype at all ... you are not answering the question.Neonate
Totally agree with @floww. It is not an answer at all.Tonie
C
-2

It turned out I needed to use the @alias keyword. http://usejsdoc.org/tags-alias.html

Cubiform answered 27/12, 2014 at 11:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.