Лучший способ документировать анонимные объекты и функции с помощью jsdoc

Изменить: технически это вопрос из двух частей. Я выбрал лучший ответ, который охватывает вопрос в целом и связан с ответом, касающимся конкретного вопроса.

Как лучше всего документировать анонимные объекты и функции с помощью jsdoc?

/**
 * @class {Page} Page Class specification
 */
var Page = function() {

    /**
     * Get a page from the server
     * @param {PageRequest} pageRequest Info on the page you want to request
     * @param {function} callback Function executed when page is retrieved
     */
    this.getPage = function(pageRequest, callback) {
    }; 
};

Ни объект PageRequest, ни объект callback не существуют в коде. Они будут предоставлены getPage() во время выполнения. Но я хотел бы иметь возможность определить, что такое объект и функция.

Я могу уйти от создания объекта PageRequest для документирования того, что:

/**
 * @namespace {PageRequest} Object specification
 * @property {String} pageId ID of the page you want.
 * @property {String} pageName Name of the page you want.
 */
var PageRequest = {
    pageId : null,
    pageName : null
};

И это нормально (хотя я открыт для лучших способов сделать это).

Как лучше всего задокументировать функцию callback? Я хочу указать в документе, что, например, функция обратного вызова имеет вид:

callback: function({PageResponse} pageResponse, {PageRequestStatus} pageRequestStatus)

Любые идеи, как это сделать?


person Josh Johnson    schedule 03.07.2010    source источник


Ответы (6)


Вы можете документировать то, чего нет в коде, используя тег @name.

/**
 * Description of the function
 * @name IDontReallyExist
 * @function
 * @param {String} someParameter Description
*/

/**
 * The CallAgain method calls the provided function twice
 * @param {IDontReallyExist} func The function to call twice
*/
exports.CallAgain = function(func) { func(); func(); }

Вот документация по тегу @name. Вам также могут пригодиться пути имен.

person Eric    schedule 22.08.2010
comment
Действительно аккуратно! Отличный способ документировать обратные вызовы. - person oligofren; 19.06.2013
comment
Но я не понимаю, как это работает для анонимных объектов? Скажем, объект настроек, который отправляется в какую-либо функцию для создания объекта, который не виден в текущей области. - person oligofren; 19.06.2013
comment
Если вы не хотите использовать тег @name для присвоения имени вашему анонимному объекту, опишите объект, в котором он используется, это будет тело тега @param для вашего примера объекта настроек. - person Eric; 21.06.2013
comment
Также есть тег @callback. - person kzh; 23.07.2013

Вы можете использовать @callback или @typedef.

/**
 * @callback arrayCallback
 * @param  {object} element - Value of array element
 * @param  {number} index   - Index of array element
 * @param  {Array}  array   - Array itself
 */

/**
 * @param {arrayCallback} callback - function applied against elements
 * @return {Array} with elements transformed by callback
 */
Array.prototype.map = function(callback) { ... }
person kzh    schedule 23.07.2013
comment
@ChrisMoschini Спасибо. Тег @callback в ответе был связан с соответствующей страницей документации. - person kzh; 30.06.2014

Чтобы дополнить ответ Стаджика, я привел пример, показывающий, что такое JsDoc с Google Closure. Компилятор позволяет это сделать.

Обратите внимание, что задокументированные анонимные типы удаляются из сгенерированного мини-файла, а компилятор обеспечивает передачу допустимых объектов (когда это возможно). Однако, даже если вы не используете компилятор, он может помочь следующему разработчику и таким инструментам, как WebStorm (IntelliJ), понять его и обеспечить автодополнение кода.

// This defines an named type that you don't need much besides its name in the code
// Look at the definition of Page#getPage which illustrates defining a type inline
/**  @typedef { pageId : string, pageName : string, contents: string} */
var PageResponse;

/**
 * @class {Page} Page Class specification
 */
var Page = function() {    
    /**
     * Get a page from the server
     * @param {PageRequest} pageRequest Info on the page you want to request
     *
     * The type for the second parameter for the function below is defined inline
     *
     * @param {function(PageResponse, {statusCode: number, statusMsg: string})} callback
     *        Function executed when page is retrieved
     */
    this.getPage = function(pageRequest, callback) {
    }; 
};
person Juan Mendes    schedule 18.04.2013
comment
Привет, это кажется самым элегантным ответом, однако вывод JSDoc просто содержит function без ввода конкретного параметра. Я использую jsdoc 3.4.0. Этот синтаксис не полностью поддерживается? - person ᆼᆺᆼ; 18.07.2016
comment
@ПитВ. Я не поспеваю за уровнем синхронизации между jsdoc и компилятором закрытия. Я бы порекомендовал вам взглянуть на альтернативные генераторы документов, которые созданы для работы с компилятором закрытия (поскольку это надмножество стандарта jsdoc). Попробуйте plovr.com , seehuhn.de/pages/jvjsdoc или github.com/google/closure-compiler/wiki/ . Я перешел к использованию TypeScript для добавления статической типизации в JavaScript. - person Juan Mendes; 18.07.2016

@link может добавлять встроенные ссылки на методы и классы.

/**
 * Get a page from the server
 * @param {PageRequest} pageRequest Info on the page you want to request
 * @param {function} callback Function executed when page is retrieved<br />
 * function({@link PageResponse} pageResponse,{@link PageRequestStatus} pageRequestStatus)
 */
this.getPage = function (pageRequest, callback) {
};

Не идеально, но со своей задачей справляется.

person Josh Johnson    schedule 06.07.2010

Аннотации Google Closure Compiler содержат выражения типов для это включает в себя возможность указать тип для определенных аргументов, тип возвращаемого значения и даже это. Многие библиотеки следят за аннотациями Google Closure Compiler, потому что хотят использовать их для сжатия своего кода. Так что у него есть некоторый импульс. Недостатком является то, что я не вижу способа дать описание.

Для предоставления описания, возможно, подойдет подход JSDoc Toolkit Parameters With Properties ( смотрите внизу страницы). Это то, что я делаю прямо сейчас. JSDoc Toolkit готовится начать работу над версией 3, поэтому отзывы могут быть хорошими.

person studgeek    schedule 23.02.2011

Вы можете использовать @see для ссылки на другой метод в том же классе. Этот метод никогда не будет использоваться, он будет использоваться только для целей документации.

/**
 * @class {Page} Page Class specification
 */
var Page = function() {

    /**
     * Get a page from the server
     * @param {PageRequest} pageRequest Info on the page you want to request
     * @param {function} callback Function executed when page is retrieved
     * @see #getPageCallback 
     */
    this.getPage = function (pageRequest, callback) {
    }; 

    /**
     * Called when page request completes 
     * @param {PageResponse} pageResponse The requested page
     * @param {PageRequestStatus} pageRequestStatus Status of the page
     */
    //#ifdef 0
    this.getPageCallback = function (pageResponse, pageRequestStatus) { };
    //#endif 
};

Если вы используете какую-то систему сборки, фиктивный метод можно легко исключить из сборки.

person Dagg Nabbit    schedule 06.07.2010
comment
Спасибо, нет. Я делаю это в настоящее время (без ifdef), и это работает, но я хотел бы, чтобы пользователь мог сразу увидеть, что это функция, которая принимает параметры X и Y, не покидая того места, где они находятся. Подобно тому, как это делает API карты Google. пример: code.google.com/apis/maps/documentation/ JavaScript/ - person Josh Johnson; 06.07.2010
comment
Только что узнал, что @link может делать то, о чем я говорю. Это не идеально, но это работает. Я создам отдельный ответ, если кто-то еще найдет его полезным. - person Josh Johnson; 06.07.2010