【问题标题】:Can JSDoc document dynamically generated methods?JSDoc 可以记录动态生成的方法吗?
【发布时间】:2016-03-16 16:52:18
【问题描述】:

这是一个构造函数A,它为实例提供了两种方法:printThingprintBall。我使用JSDoc 来记录这样的方法:

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++
        }
    };

};

这是一个等效的构造函数,它可以像这样动态生成相同的方法:

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');
}

两个构造函数生成的实例的行为是相同的:

> var a = new A();
> a.printBall(4);
Ball
Ball
Ball
Ball

如何使用 JSDoc 记录第二个 A 构造函数中生成的方法?


编辑:registerPrinter 在构造函数范围内是私有的。它可以(并且应该)记录在案,但它只是在内部使用。这个问题是关于记录A 实例的公共接口。

【问题讨论】:

标签: javascript jsdoc


【解决方案1】:

@name 就是为此而生的:

这个标签最好用在“虚拟cmets”中,用于在代码中不容易看到的符号...

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.
     */
}

【讨论】:

  • 这是一个很好的解决方案,比我自己的答案更直接地回答了我的问题。感谢您抽出宝贵时间回答!
  • 很好的解决方案。但我想知道对于许多动态生成的方法来说,如何更容易做到这一点。把它们都写下来可能很乏味。
  • 我最终使用了一个脚本,该脚本根据我的一些逻辑将文档输出到另一个 .js 文件。然后我对主目标文件和生成的文件都使用了 jsdoc 命令。对于我的 30 多种动态生成方法的情况,效果非常好。
  • @keshav.bahadoor 没有看到你的代码很难判断,但如果你可以动态生成方法和文档(他们在做同样的事情?)也许你应该考虑不生成 30方法。
【解决方案2】:

在搜索了一天的文档后,这是我能找到的最佳选择。它需要对A 稍有不同的等效定义,并更改为registerPrinter。它略显冗长,但保留了不重复非常相似的方法的可维护性优势,并且更具可读性:

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');
}

请注意,这不再是动态地将属性printThingprintBall 添加到this(尽管这些方法仍然是动态生成的)。因此,这不是问题的直接解决方案 - 它是一种解决方法。 我将接受任何实际记录动态添加属性的未来答案。

【讨论】:

    【解决方案3】:

    为什么不只记录编写的代码?

    var A = function() {
    
      var me = this;
    
      /**
       * [function description]
       * @param  {[type]} name [description]
       * @return {[type]}      [description]
       */
      var registerPrinter = function(name) {
    
        /**
         * [function description]
         * @param  {[type]} N [description]
         * @return {[type]}   [description]
         */
        me['print' + name] = function(N) {
          var i = 0;
          while (i < N) {
            console.log(name);
            i++;
          }
        };
      };
    
      registerPrinter('Thing');
      registerPrinter('Ball');
    };
    

    【讨论】:

    • 感谢您的回复。 registerPrinter 在构造函数范围内是私有的。它可以(并且应该)记录在案,但它只是在内部使用。我想记录A 实例的公共接口。抱歉,不清楚 - 我会在我的问题中说明这一点。
    猜你喜欢
    • 2014-08-06
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2012-08-12
    相关资源
    最近更新 更多