JSDoc является стандартом де-факто для документирования кода JavaScript. Вам нужно знать хотя бы его синтаксис (который также используется многими другими инструментами), если вы публикуете код. Увы, документации по-прежнему мало, но этот пост может помочь — он показывает, как запустить JSDoc и как работает его синтаксис. (JSDoc wiki [2] является основным источником этого поста, некоторые примеры заимствованы из него.)
В качестве инструмента JSDoc берет код JavaScript со специальными комментариями / ** * / и создает для него HTML-документацию. Например: учитывая следующий код.
/** @namespace */ var util = { /** * Repeat <tt>str</tt> several times. * @param {string} str The string to repeat. * @param {number} [times=1] How many times to repeat the string. * @returns {string} */ repeat: function(str, times) { if (times === undefined || times < 1) { times = 1; } return new Array(times+1).join(str); } };
Сгенерированный HTML выглядит следующим образом в веб-браузере:
Этот пост начинается с быстрого начала, поэтому вы можете попробовать JSDoc немедленно, если вы нетерпеливы. После этого предоставляется дополнительная справочная информация.
1. Быстрый старт
Для действий, описанных ниже, вам нужно установить Java. JSDoc включает в себя сценарий оболочки jsrun.sh, для работы которого требуется Unix (включая OS X и Linux). Но должно быть легко перевести этот скрипт в командный файл Windows.
- Загрузите последнюю версию jsdoc_toolkit . Распакуйте архив, скажем, в $ HOME / jsdoc-toolkit.
- Сделайте скрипт $ HOME / jsdoc-toolkit / jsrun.sh исполняемым и скажите ему, где искать двоичный файл JSDoc и шаблон (который контролирует, как будет выглядеть результат).
JSDOCDIR="$HOME/local/jsdoc-toolkit" JSDOCTEMPLATEDIR="$JSDOCDIR/templates/jsdoc"
Теперь вы можете переместить скрипт куда угодно, например, в каталог bin /. Для этой демонстрации мы не перемещаем сценарий.
- Используйте jsrun.sh для каталога файлов JavaScript:
$HOME/jsdoc-toolkit/jsrun.sh -d=$HOME/doc $HOME/js
- Входные данные: $ HOME / js — каталог файлов JavaScript (см. Пример ниже).
- Вывод: $ HOME / doc — куда записать сгенерированные файлы.
Если вы поместите код JavaScript в начале этого поста в файл $ HOME / js / util.js, то JSDoc создаст следующие файлы:
$HOME/doc +-- files.html +-- index.html +-- symbols +-- _global_.html +-- src ¦ +-- util.js.html +-- util.html
2. Введение: что такое JSDoc?
Это общая проблема программирования: вы написали код JavaScript, который будет использоваться другими, и вам нужна красивая HTML-документация его API. Java впервые внедрила этот домен с помощью инструмента JavaDoc. Квази-стандартом в мире JavaScript является JSDoc. Как показано выше, вы документируете сущность, помещая перед ней специальный комментарий, который начинается с двух звездочек.
Шаблоны. Чтобы что-то выводить, JSDoc всегда нужен шаблон , смесь JavaScript и специально размеченный HTML, который объясняет, как перевести проанализированную документацию в HTML. JSDoc поставляется со встроенным шаблоном, но есть и другие, которые вы можете скачать [3].
2.1. Терминология и соглашения JSDoc
- Доклет: JSDoc вызывает свои комментарии doclets, что противоречит терминологии JavaDoc, где такие комментарии называются комментариями документа, а доклет похож на шаблон JSDoc, но написан на Java.
- Переменная: термин переменная в JSDoc часто относится ко всем документируемым объектам, которые включают в себя глобальные переменные, свойства объекта и внутренние члены.
- Свойства экземпляра: в JavaScript обычно помещают методы в прототип, чтобы делиться ими со всеми экземплярами класса, в то время как поля (нефункциональные свойства) помещаются в каждый экземпляр. JSDoc объединяет общие свойства и свойства каждого экземпляра и вызывает их свойства экземпляра .
- Свойства класса, статические свойства: это свойства классов, обычно функций конструктора. Например, Object.create является свойством класса Object.
- Внутренние члены: внутренний член — это данные, вложенные в функцию. Наиболее важными для документации являются личные данные экземпляра, вложенные в функцию конструктора.
function MyClass() { var privateCounter = 0; // an inner member this.inc = function() { // an instance property privateCounter++; }; }
2.2. Синтаксис
Давайте рассмотрим комментарий, показанный в начале:
/** * Repeat <tt>str</tt> several times. * @param {string} str The string to repeat. * @param {number} [times=1] How many times to repeat the string. * @returns {string} */
Это демонстрирует некоторый синтаксис JSDoc, который состоит из следующих частей.
- Комментарий JSDoc: это блочный комментарий JavaScript, первым символом которого является звездочка. Это создает иллюзию, что токен / ** запускает такой комментарий.
- Теги: комментарии структурированы по начальным строкам с тегами , ключевым словам с префиксом @. @param — пример выше.
- HTML: вы можете свободно использовать HTML в комментариях JSDoc; например, <tt> для отображения слова моноширинным шрифтом.
- Аннотации типов: тип значения можно задокументировать, поместив имя типа в фигурные скобки после соответствующих тегов. Варианты:
Одиночный тип: @param {string} name Несколько типов: @param {string | number} idCode Массивы типа: @param {string []} names - Пути к именам: используются для ссылки на переменные внутри комментариев JSDoc. Синтаксис таких путей следующий.
myFunction MyConstructor MyConstructor.classProperty MyConstructor#instanceProperty MyConstructor-innerMember
2,3. Слово о типах
В JavaScript есть два вида значений: примитивы и объекты [7].
- Примитивные типы: логическое, число, строка. Значения undefined и null также считаются примитивными.
- Типы объектов. Все остальные типы являются типами объектов , включая массивы и функции.
Осторожно: имена примитивных типов начинаются со строчной буквы. Каждый примитивный тип имеет соответствующий
тип оболочки, тип объекта с заглавным именем, экземплярами которого являются объекты:
- Тип оболочки boolean — Boolean.
- Тип обертки числа — Число.
- Тип обёртки строки — String.
Получение имени типа значения:
- Примитивное значение p: через typeof p.
> typeof "" 'string'
Сравните: экземпляр типа оболочки является объектом.
> typeof new String() 'object'
- Значение объекта o: через o.constructor.name. Пример:
> new String().constructor.name 'String'
3. Основные теги
Мета-данные:
- @fileOverview: отмечает комментарий JSDoc, который описывает весь файл.
- @author: Кто написал задокументированную переменную?
- @deprecated: указывает, что переменная больше не поддерживается. Рекомендуется задокументировать, что использовать вместо этого.
- @example: содержит пример кода, иллюстрирующий, как следует использовать данный объект.
/** * @example * var str = "abc"; * console.log(repeat(str, 3)); // abcabcabc */
Связь:
- @see: указывает на связанный ресурс.
/** * @see MyClass#myInstanceMethod * @see The <a href="http://example.com">Example Project</a>. */
- {@link …}: работает как @see, но может использоваться внутри других тегов.
- @requires resourceDescription : ресурс, в котором нуждается документированный объект. Описание ресурса — это либо путь к имени, либо описание на естественном языке.
Versioning:
- @version VersionNumber : указывает версию документированной лица. Пример:
@version 10.3.1
- @since VersionNumber : указует , так какую версию документированной сущность была доступна. Пример:
@since 10.2.0
4. Документирование функций и методов
Для функций и методов можно задокументировать параметры, возвращаемые значения и исключения, которые они могут генерировать.
- @param { paramType } paramName description : описывает параметр с именем paramName . Тип и описание не являются обязательными. Примеры:
@param str @param str The string to repeat. @param {string} str @param {string} str The string to repeat.
Расширенные возможности:
- Необязательный параметр:
@param {number} [times] The number of times is optional.
- Необязательный параметр со значением по умолчанию:
@param {number} [times=1] The number of times is optional.
- Необязательный параметр:
- @returns { returnType } description : описывает возвращаемое значение функции или метода. Тип или описание могут быть опущены.
- @throws { exceptionType } description : описывает исключение, которое может быть вызвано во время выполнения функции или метода. Тип или описание могут быть опущены.
4.1. Встроенная информация о типе («встроенные комментарии документа»)
Существует два способа предоставления информации о типе для параметров и возвращаемых значений. Во-первых, вы можете добавить аннотацию типа к @param и @returns.
/** * @param {String} name * @returns {Object} */ function getPerson(name) { }
Во-вторых, вы можете вставить информацию о типе:
function getPerson(/**String*/ name) /**Object*/ { }
5. Документирование переменных и полей
Поля — это свойства с нефункциональными значениями. Поскольку поля экземпляра часто создаются внутри конструктора, вы должны документировать их там.
- @type { typeName }: какой тип имеет документированная переменная? Пример:
/** @constructor */ function Car(make, owner) { /** @type {string} */ this.make = make; /** @type {Person} */ this.owner = owner; } @type {Person}
Этот тег также можно использовать для документирования возвращаемого типа функций, но в этом случае предпочтительным является @returns.
- @constant: флаг, который указывает, что документированная переменная имеет постоянное значение.
- @default defaultValue : каково значение переменной по умолчанию? Пример:
/** @constructor */ function Page(title) { /** * @default "Untitled" */ this.title = title || "Untitled"; }
- @property { propType } propName description : задокументируйте свойство экземпляра в комментарии класса. Пример:
/** * @class * @property {string} name The name of the person. */ function Person(name) { this.name = name; }
Без этого тега свойства экземпляра документируются следующим образом.
/** * @class */ function Person(name) { /** * The name of the person. * @type {string} */ this.name = name; }
Какой из этих стилей использовать — дело вкуса. Хотя @property вносит избыточность.
6. Документирование занятий
Встроенные в JavaScript средства для определения классов слабы, поэтому существует много API, которые помогают с этой задачей [5]. Эти API отличаются, часто радикально, поэтому вы должны помочь JSDoc выяснить, что происходит. Существует три основных способа определения класса:
- Функция конструктора: Вы должны пометить функцию конструктора, иначе она не будет задокументирована как класс. То есть одна только заглавная буква не помечает функцию как конструктор.
/** * @constructor */ function Person(name) { }
@class — это синоним @constructor, но он также позволяет вам описать класс — в отличие от функции, устанавливающей экземпляр (пример см. в документации по тегам ниже).
- Вызов API и литерал объекта: вам нужны два маркера. Во-первых, вам нужно сообщить JSDoc, что данная переменная содержит класс. Во-вторых, вам нужно пометить литерал объекта как определяющий класс. Последнее делается через тег @lends.
/** @class */ var Person = makeClass( /** @lends Person# */ { say: function(message) { return "This person says: " + message; } } );
- Вызов API и литерал объекта с помощью метода конструктора: если один из методов в литерале объекта выполняет задачу конструктора (настройка данных экземпляра, [8]), необходимо пометить его так, чтобы поля были найдены JSDoc. , Затем документация класса перемещается в этот метод.
var Person = makeClass( /** @lends Person# */ { /** * A class for managing persons. * @constructs */ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + " says: " + message; } } );
Метки:
- @constructor: помечает функцию как конструктор.
- @class: помечает переменную как класс или функцию как конструктор. Может использоваться в комментарии конструктора, чтобы отделить описание конструктора (первая строка ниже) от описания класса (вторая строка ниже).
/** * Creates a new instance of class Person. * @class Represents a person. */ Person = function() { }
- @constructs: помечает метод в литерале объекта как выполняющий обязанности конструктора. То есть настройка данных экземпляра. В таком случае класс должен быть там задокументирован. Работает в паре с @lends.
- @lends namePath : указывает, к какому классу относится следующий литерал объекта. Есть два способа внести свой вклад.
- @lends Person # — литерал объекта передает свойства экземпляра Person.
- @lends Person — литерал объекта добавляет свойства класса Person.
6.1. Наследование, пространство имен
В JavaScript нет простой поддержки подклассов и нет реальных пространств имен [6]. Таким образом, вы должны помочь JSDoc увидеть, что происходит, когда вы используете обходные пути.
- @extends namePath : указывает, что документированный класс является подклассом другого. Пример:
/** * @constructor * @extends Person */ function Programmer(name) { Person.call(this, name); ... } // Remaining code for subclassing omitted
- @augments: синоним @extends.
- @namespace: объекты можно использовать для имитации пространств имен в JavaScript. Этот тег отмечает такие объекты. Пример:
/** @namespace */ var util = { ... };
7. Метатеги
Мета-теги — это теги, которые добавляются к нескольким переменным. Вы помещаете их в комментарий, который начинается с «/ ** # @ +». Затем они добавляются ко всем переменным, пока JSDoc не встретит заключительный комментарий «/ ** # @ — * /». Пример:
/**#@+ * @private * @memberOf Foo */ function baz() {} function zop() {} function pez() {} /**#@-*/
8. Редко используемые теги
- @ignore: игнорировать переменную. Обратите внимание, что переменные без / ** комментариев игнорируются.
- @borrows otherNamePath как это. propName : переменная — это просто ссылка на другое место; это задокументировано там. Пример:
/** * @constructor * @borrows Remote#transfer as this.send */ function SpecialWriter() { this.send = Remote.prototype.transfer; }
- @ описание текста : введите описание, такое же, как весь текст перед первым тегом.
Ручная категоризация. Иногда JSDoc неправильно интерпретирует, что такое переменная. Тогда вы можете помочь с помощью одного из следующих тегов:
Тег Пометить переменную как @function функция @field нефункциональное значение @public общедоступный (особенно внутренние переменные) @частный частный @inner внутренний и, следовательно, также частный @static доступны без инстанциирования
Имя и членство:
- @ name namePath : переопределить проанализированное имя и использовать вместо него указанное имя.
- @memberOf parentNamePath : документированная переменная является членом указанного объекта.
Не объяснено здесь:
@event , см. [2].
9. Связанное чтение
- jsdoc-toolkit — Генератор документации для JavaScript : домашняя страница JSDoc в Google Code. Включает ссылку на загрузку.
- JSDoc wiki : официальная документация JSDoc и источник этого поста.
- JSDoc wiki — TemplateGallery : список доступных шаблонов JSDoc.
- JSDoc wiki — TagReference : удобная шпаргалка для тегов JSDoc.
- Облегченные API наследования JavaScript
- Модули и пространства имен в JavaScript
- Значения JavaScript: не все является объектом
- Прототипы как классы — введение в наследование JavaScript