让jsdoc和Crockford的设计模式相容

9

我正在使用道格拉斯·克罗克福德的设计模式来实现私有、特权和公共方法。它大致看起来像这样(使用RequireJS):

define(function () {
    return function () {
        var that = {},

        _init = function () {
            // "constructor"
        },

        _privateFn = function () {
            return 42;
        };

        that.publicFn = function () {
            return 2 * _privateFn();
        };

        _init(arguments);

        return that;
    };
});

然而,我在使用jsdoc工具包解析它时遇到了麻烦。我尝试过调整@name@memberOf注释(例如这里),但无论我做什么,都无法显示函数。
有人知道解决方法吗?

1
哇,我简直不敢相信没有人知道任何事情(或似乎不关心)。让我们把这个家伙的赏金提高。 - n3rd
1
这可能不是你问题的根源,但我希望你在每个私有函数前面加上 var - David Tang
实际上,_init函数后面的分号应该是逗号。谢谢,我会更新帖子。 - n3rd
5个回答

16

好的,我终于搞清楚了。这就是如何做到的:

/**
* @name MyModule
* @namespace
*/
define(['MyModule'], (function () {
    "use strict";

    var Clazz = function (config) {
        var that = {},

        /**
        * @private
        * @type number
        * @name MyModule#_privateField
        * @field
        */
        _privateField = 42,

        /**
        * Returns a private field
        * 
        * @private
        * @memberOf MyModule#
        */
        _privateFn = function () {
            return _privateField;
        };

        /**
        * Uppercases a string value.
        * 
        * @public
        * @name MyModule#publicFn
        * @function
        * @param {string} value The value to uppercase.
        */
        that.publicFn = function (value) {
            return value.toUpperCase();
        };

        return that;
    }

    return Clazz;
}));

+1 我刚开始使用jsdoc3,最初感到沮丧,因为除了模块描述和名称之外,我无法让jsdoc识别其他内容。您的答案解决了这个问题。 - Mike Moore
看我的回答,使用 @lends 要比这个困难得多。 - Eli

2

我曾经也尝试着使用标签来让JsDoc Toolkit在动态构建时输出一些有意义的内容,这让我感到很有趣。

即使我已经成功了,它仍然存在一些奇怪的缺陷,需要我一次又一次地调整标签,它看起来并不吸引人,而且仍然不能代替适当的文档 - 你可能会读源代码中的那些注释。

说实话,我所做的最好的事情就是把我花费在JsDoc Toolkit上跳跃的时间,用来编写一些真正的文档,使用Sphinx

除了由人们编写的任何有指导性的文档相比自动生成的API文档固有的优势外,Sphinx还具有JavaScript域指令,允许您记录API的最终状态,这将向最终用户公开,而不是让一些代码试图通过查看散布在您的代码中的试错注释来理解API。


谢谢,看起来非常有趣。我下周会去查看一下。 - n3rd

1
我在寻找解决同样问题的方案时找到了这个问题。我最终找到了一种更好的方法来解决这个问题,如果您不介意记录私有方法/变量(考虑到它们实际上是局部变量,无法从其他任何地方访问,您可能不应该这样做)。 它使用@alias指令,在JSDoc 3中是新功能。
/**
* @name MyModule
* @namespace
*/
define(['MyModule'], (function () {
    "use strict";

    var Clazz = function (config) {
        /** @alias MyModule.prototype */
        var that = {};

        /**
        * Uppercases a string value.
        * @param {string} value The value to uppercase.
        */
        that.publicFn = function (value) {
            return value.toUpperCase();
        };

        return that;
    }

    return Clazz;
}));

我想记录下所有我的代码,即使其中一些可能永远不会出现在公共apidocs中。我已经很久以前切换到了jsduck,但还是谢谢。 - n3rd

1

不知道你尝试时是否存在,但是@lends的使用方式要好得多。

See: http://usejsdoc.org/tags-lends.html

例子:

var Person = makeClass(
/** @lends Person.prototype */
{
    /** @constructs */
    initialize: function(name) {
        this.name = name;
    },
    say: function(message) {
        return this.name + " says: " + message;
    }
});

如果你没有构造函数怎么办?这不是工厂的有效文档。 - Danielo515
如果您没有构造函数,则可以像上面那样使用 @name 和 @namespace(如果相关)。对于具有构造函数的对象,我认为 @lends 和 @constructs 是最佳选项。 - Eli

0

实际上我认为Douglas Crockford的面向对象编程模式是反模式。我通过艰难的方式学习到不要使用它们。这篇文章总结了它们的缺点: http://bolinfest.com/javascript/inheritance.php

所以解决方案是忘记Crockford的反模式,从那些实际撰写真正代码的开发者那里学习。

如果您坚持使用私有方法,我建议您使用Google Closure Compiler及其注释,您可以在此处查看:http://code.google.com/closure/compiler/docs/js-for-compiler.html


嗯,使用一种特定的工具来规避另一个工具的缺点并不是我所谓的解决方案。此外,在查看了下面的文章之后,我并不完全确定由Google开发人员编写的工具是正确的选择:http://blogs.sitepoint.com/2009/11/12/google-closure-how-not-to-write-javascript/(当然,这篇文章相当老了。但你提供的那篇也是)。 - n3rd
Crockord本人声称他从未在JS中使用过经典的OOP模仿。@n3rd,如果您解释一下它遇到了解析问题,可能会有所帮助。我对JSDoc不太了解,但如果我们看到它出现故障的地方,它可能会变得明显。 - Erik Reppen
它没有崩溃,运行得很好。只是它不会为我的函数生成文档 :-/ - n3rd
我也无法忍受Crockford的设计模式。然而,这并没有真正回答问题,最好作为一条评论。 - Ruan Mendes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接