javascript 我如何 JSDoc 嵌套对象的方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19230971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 14:49:42  来源:igfitidea点击:

How do I JSDoc A Nested Object's Methods?

javascriptrequirejsjsdocjsdoc3

提问by machineghost

I've been trying to use JSDoc3 to generate documentation on a file, but I'm having some difficulty. The file (which is a Require.js module) basically looks like this:

我一直在尝试使用 JSDoc3 来生成文件的文档,但我遇到了一些困难。该文件(这是一个 Require.js 模块)基本上如下所示:

define([], function() {

    /*
     * @exports mystuff/foo
     */
    var foo = {
        /**
         * @member
         */
        bar: {
            /**
             * @method
             */
            baz: function() { /*...*/ }
        }
    };

    return foo;
}

The problem is, I can't get bazto show up in the generated documentation. Instead I just get a documentation file for a foo/foomodule, which lists a barmember, but barhas no baz(just a link to foo's source code).

问题是,我无法baz显示在生成的文档中。相反,我只是得到一个foo/foo模块的文档文件,其中列出了一个bar成员,但bar没有baz(只是一个指向foo源代码的链接)。

I've tried changing bar's directive to @propertyinstead, and I've tried changing baz's directive to @memberor @property, but none of that helps. No matter what I do, baz just doesn't seem to want to show up.

我尝试将bar's 指令改为@property改为,我也尝试将baz's 指令改为@memberor @property,但这些都没有帮助。不管我做什么,巴兹似乎都不想出现。

Does anyone know what directive structure I could use to get baz to appear in the generated documentation?

有谁知道我可以使用什么指令结构让 baz 出现在生成的文档中?

P.S. I've tried reading pages like this one on the JSDoc site http://usejsdoc.org/howto-commonjs-modules.html, but it only describes cases of foo.bar, not foo.bar.baz.

PS 我试过在 JSDoc 站点http://usejsdoc.org/howto-commonjs-modules.html上阅读这样的页面,但它只描述了foo.bar,而不是foo.bar.baz.

回答by Mohit

You can use a combination of @moduleor @namespacealong with @memberof.

您可以将@module@namespace@memberof结合使用。

define([], function() {

    /**
     * A test module foo
     * @version 1.0
     * @exports mystuff/foo
     * @namespace foo
     */
    var foo = {
        /**
         * A method in first level, just for test
         * @memberof foo
         * @method testFirstLvl
         */
        testFirstLvl: function(msg) {},
        /**
         * Test child object with child namespace
         * @memberof foo
         * @type {object}
         * @namespace foo.bar
         */
        bar: {
            /**
             * A Test Inner method in child namespace
             * @memberof foo.bar
             * @method baz
             */
            baz: function() { /*...*/ }
        },
        /**
         * Test child object without namespace
         * @memberof foo
         * @type {object}
         * @property {method} baz2 A child method as property defination
         */
        bar2: {
            /**
             * A Test Inner method
             * @memberof foo.bar2
             * @method baz2
             */
            baz2: function() { /*...*/ }
        },
        /**
         * Test child object with namespace and property def.
         * @memberof foo
         * @type {object}
         * @namespace foo.bar3
         * @property {method} baz3 A child method as property defination
         */
        bar3: {
            /**
             * A Test Inner method in child namespace
             * @memberof foo.bar3
             * @method baz3
             */
            baz3: function() { /*...*/ }
        },
        /**
         * Test child object
         * @memberof foo
         * @type {object}
         * @property {method} baz4 A child method
         */
        bar4: {
             /**
             * The @alias and @memberof! tags force JSDoc to document the
             * property as `bar4.baz4` (rather than `baz4`) and to be a member of
             * `Data#`. You can link to the property as {@link foo#bar4.baz4}.
             * @alias bar4.baz4
             * @memberof! foo#
             * @method bar4.baz4
             */
            baz4: function() { /*...*/ }
        }
    };

    return foo;
});

EDIT as per Comment:(Single page solution for module)

根据评论编辑:(模块的单页解决方案)

bar4 without that ugly property table. ie @property removed from bar4.

bar4 没有那个丑陋的属性表。即@property 从 bar4 中删除。

define([], function() {

    /**
     * A test module foo
     * @version 1.0
     * @exports mystuff/foo
     * @namespace foo
     */
    var foo = {
        /**
         * A method in first level, just for test
         * @memberof foo
         * @method testFirstLvl
         */
        testFirstLvl: function(msg) {},
        /**
         * Test child object
         * @memberof foo
         * @type {object}
         */
        bar4: {
             /**
             * The @alias and @memberof! tags force JSDoc to document the
             * property as `bar4.baz4` (rather than `baz4`) and to be a member of
             * `Data#`. You can link to the property as {@link foo#bar4.baz4}.
             * @alias bar4.baz4
             * @memberof! foo#
             * @method bar4.baz4
             */
            baz4: function() { /*...*/ },
            /**
             * @memberof! for a memeber
             * @alias bar4.test
             * @memberof! foo#
             * @member bar4.test
             */
             test : true
        }
    };

    return foo;
});

References -

参考 -

  1. Another Question about nested namespaces
  2. For alternative way of using Namespaces
  3. Documenting literal objects
  1. 关于嵌套命名空间的另一个问题
  2. 对于使用命名空间的替代方式
  3. 记录文字对象

*NoteI haven't tried it myself. Please try and share the results.

*注意我自己没有尝试过。请尝试并分享结果。

回答by Louis

Here's a simple way to do it:

这是一个简单的方法:

/**
 * @module mystuff/foo
 * @version 1.0
 */
define([], function() {

/** @lends module:mystuff/foo */
var foo = {
    /**
     * A method in first level, just for test
     */
    testFirstLvl: function(msg) {},
    /**
     * @namespace
     */
    bar4: {
        /**
         * This is the description for baz4.
         */
        baz4: function() { /*...*/ },
        /**
         * This is the description for test.
         */
        test : true
    }
};

return foo;
});

Note that jsdoc can infer the types baz4.baz4and testwithout having to say @method and @member.

请注意,jsdoc 可以推断类型baz4.baz4test而不必说@method 和@member。

As far as having jsdoc3 put documentation for classes and namespaces on the samepage as the module that defines them, I don't know how to do it.

至于让 jsdoc3 将类和命名空间的文档与定义它们的模块放在同一页面上,我不知道该怎么做。

I've been using jsdoc3 for months, documenting a small libraryand a large applicationwith it. I prefer to bend to jsdoc3's will in some areas than have to type reams of @-directives to bend it to my will.

我已经使用 jsdoc3 几个月了,用它记录了一个小型库和一个大型应用程序。我更喜欢在某些领域屈从于 jsdoc3 的意愿,而不是必须键入大量的 @-directives 来屈从于我的意愿。

回答by risto

You can't document nested functions directly. I didn't like Prongs solution, so I used a different implementation without namespaces (it's JS, notJava!).

您不能直接记录嵌套函数。我不喜欢 Prongs 解决方案,所以我使用了一个没有命名空间的不同实现(它是 JS,不是Java!)。

Update:

更新:

I updated my answer to reflect the exact use case given by the OP (which is fair, since JSdoc is pretty painful to use). Here is how it would work:

我更新了我的答案以反映 OP 给出的确切用例(这是公平的,因为 JSdoc 使用起来非常痛苦)。这是它的工作原理:

/** @module foobar */

/** @function */
function foobarbaz() {
    /* 
     * You can't document properties inside a function as members, like you
     * can for classes. In Javascript, functions are first-class objects. The
     * workaround is to make it a @memberof it's closest parent (the module).
     * manually linking it to the function using (see: {@link ...}), and giving
     * it a @name.
     */

    /**
     * Foo object (see: {@link module:foobar~foobarbaz})
     * @name foo
     * @inner
     * @private
     * @memberof module:foobar
     * @property {Object} foo - The foo object
     * @property {Object} foo.bar - The bar object
     * @property {function} foo.bar.baz - The baz function
     */
    var foo = {

        /* 
         * You can follow the same steps that was done for foo, with bar. Or if the
         * @property description of foo.bar is enough, leave this alone. 
         */
        bar: {

            /*
             * Like the limitation with the foo object, you can only document members 
             * of @classes. Here I used the same technique as foo, except with baz.
             */

            /**
             * Baz function (see: {@link module:foobar~foo})
             * @function
             * @memberof module:foobar
             * @returns {string} Some string
             */
            baz: function() { /*...*/ }
        }
    };

    return foo;
}

Unfortunately JSdoc is a port of Java, so it has a lot of features that make sense for Java but not for JS, and vice-versa. For example, since in JS functions are first-class objects, they can be treated as objects or functions. So doing something like this should work:

不幸的是,JSdoc 是 Java 的一个端口,所以它有很多对 Java 有意义但对 JS 没有意义的特性,反之亦然。例如,由于在 JS 中函数是一等对象,因此它们可以被视为对象或函数。所以做这样的事情应该有效:

/** @function */
function hello() {
  /** @member {Object} */
  var hi = {};
}

But it won't, because JSdoc recognizes it as a function. You would have to use namespaces, my technique with @link, or to make it a class:

但它不会,因为 JSdoc 将它识别为一个函数。您将不得不使用命名空间,我的技术与@link, 或使其成为一个类:

/** @class */
function Hello() {
  /** @member {Object} */
  var hi = {};
}

But then that doesn't make sense either. Do classes exist in JS?no, they don't.

但这也没有意义。JS 中是否存在类?,他们没有。

I think we really need to find a better documentation solution. I've even seen inconsistencies in the documentation for with how types should be displayed (e.g. {object}vs {Object}).

我认为我们真的需要找到一个更好的文档解决方案。我什至在文档中看到了关于如何显示类型的不一致(例如{object}vs {Object})。

You can also use my technique to document closures.

你也可以使用我的技巧来记录闭包

回答by Xunnamius

Just to improve on Prongs's answer a bit for JSDoc3, I was only able to get it to work when I used the @instanceannotation in lieu of @member.

只是为了改进ProngsJSDoc3的回答,只有当我使用@instance注释代替@member时,我才能让它工作。

ES6 example code follows:

ES6 示例代码如下:

class Test
{
    /**
     * @param {object} something
     */
    constructor(something)
    {
        this.somethingElse = something;

        /**
         * This sub-object contains all sub-class functionality.
         *
         * @type {object}
         */
        this.topology = {
            /**
             * Informative comment here!
             *
             * @alias topology.toJSON
             * @memberof! Test#
             * @instance topology.toJSON
             * 
             * @returns {object} JSON object
             */
            toJSON()
            {
                return deepclone(privatesMap.get(this).innerJSON);
            },


            ...
        }
    }
}