Beste Möglichkeit, anonyme Objekte und Funktionen mit jsdoc zu dokumentieren

71

Bearbeiten: Dies ist technisch eine zweiteilige Frage. Ich habe die beste Antwort ausgewählt, die die Frage im Allgemeinen abdeckt, und sie mit der Antwort verknüpft, die die spezifische Frage behandelt.

Was ist der beste Weg, um anonyme Objekte und Funktionen mit jsdoc zu dokumentieren?

/**
 * @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) {
    }; 
};

Weder das PageRequestObjekt noch das callbackexistieren im Code. Sie werden zur getPage()Laufzeit zur Verfügung gestellt. Aber ich möchte in der Lage sein zu definieren, was das Objekt und die Funktion sind.

Ich kann mit dem Erstellen des PageRequestObjekts davonkommen, um Folgendes zu dokumentieren:

/**
 * @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
};

Und das ist in Ordnung (obwohl ich offen bin für bessere Möglichkeiten, dies zu tun).

Wie kann die callbackFunktion am besten dokumentiert werden? Ich möchte im Dokument darauf hinweisen, dass die Rückruffunktion beispielsweise folgende Form hat:

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

Irgendwelche Ideen, wie das geht?

Josh Johnson
quelle

Antworten:

55

Mit dem @ name-Tag können Sie Dinge dokumentieren, die im Code nicht vorhanden sind.

/**
 * 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(); }

Hier ist die Dokumentation zum @ name-Tag . Möglicherweise sind auch Namenspfade hilfreich.

Eric
quelle
Wirklich ordentlich! Eine großartige Möglichkeit, Rückrufe zu dokumentieren.
Oligofren
1
Aber ich sehe nicht, wie das für anonyme Objekte funktioniert? Angenommen, ein Einstellungsobjekt wird an eine Funktion gesendet, um ein Objekt zu erstellen, das im aktuellen Bereich nicht sichtbar ist.
Oligofren
1
Wenn Sie das @nameTag nicht verwenden möchten, um Ihrem anonymen Objekt einen Namen zu geben, beschreiben Sie das Objekt, in dem es verwendet wird. @paramDies ist der Hauptteil des Tags für das Beispiel Ihres Einstellungsobjekts.
Eric
2
Es gibt auch das @callbackTag.
kzh
47

Sie können @callbackoder verwenden @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) { ... }
kzh
quelle
4
@ ChrisMoschini Danke. Das @callbackTag in der Antwort wurde mit der entsprechenden Dokumentationsseite verknüpft.
kzh
9

Um die Antwort von studgeek zu ergänzen, habe ich ein Beispiel bereitgestellt, das zeigt, was Sie mit JsDoc mit Google Closure Compiler tun können.

Beachten Sie, dass die dokumentierten anonymen Typen aus der generierten minimierten Datei entfernt werden und der Compiler sicherstellt, dass gültige Objekte übergeben werden (wenn möglich). Selbst wenn Sie den Compiler nicht verwenden, kann er dem nächsten Entwickler und Tools wie WebStorm (IntelliJ) helfen, ihn zu verstehen und den Code zu vervollständigen.

// 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) {
    }; 
};
Juan Mendes
quelle
Hallo, dies scheint die eleganteste Antwort zu sein, jedoch enthält functiondie JSDoc-Ausgabe nur ohne die spezifische Parametertypisierung. Ich benutze jsdoc 3.4.0. Wird diese Syntax nicht vollständig unterstützt?
18 ᆺ ᆼ
1
@PeteV. Ich habe mit dem Grad der Synchronisation zwischen jsdoc und Closure Compiler nicht Schritt gehalten. Ich würde empfehlen, dass Sie sich alternative Dokumentgeneratoren ansehen, die für die Verwendung mit dem Closure Compiler entwickelt wurden (da dies eine Obermenge des jsdoc-Standards ist). Versuchen Sie es mit plovr.com , seehuhn.de/pages/jvjsdoc oder github.com/google/closure-compiler/wiki/… . Ich habe TypeScript verwendet, um JavaScript statische Typisierung hinzuzufügen
Juan Mendes
2

@link kann Inline-Links zu Methoden und Klassen hinzufügen.

/**
 * 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) {
};

Nicht ideal, aber es erledigt den Job.

Josh Johnson
quelle
1

Die Google Closure Compiler Anmerkungen haben Typ - Ausdrücke für diese , die die Fähigkeit Typen für bestimmte Argumente , um anzuzeigen , enthalten, Rückgabetyp und auch dies. Viele Bibliotheken versuchen, den Anmerkungen des Google Closure Compiler zu folgen, da sie damit ihren Code verkleinern möchten. Es hat also etwas Schwung. Der Nachteil ist, dass ich keinen Weg sehe, die Beschreibung zu geben.

Für die Bereitstellung der Beschreibung würde möglicherweise der Ansatz JSDoc Toolkit Parameters With Properties funktionieren (siehe unten auf der Seite). Es ist das, was ich gerade mache. Das JSDoc-Toolkit bereitet die Arbeit an V3 vor, sodass das Feedback dort möglicherweise gut ist.

studgeek
quelle
0

Sie können @see verwenden, um eine Verknüpfung zu einer anderen Methode innerhalb derselben Klasse herzustellen. Die Methode würde niemals verwendet werden, sondern nur zu Dokumentationszwecken.

/**
 * @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 
};

Wenn Sie ein Build-System verwenden, kann die Dummy-Methode leicht im Build weggelassen werden.

Dagg Nabbit
quelle
Danke, nein. Ich mache das gerade (ohne das ifdef) und es funktioniert, aber ich möchte, dass der Benutzer sofort sehen kann, dass es eine Funktion ist, die die Parameter X und Y akzeptiert, ohne zu belassen, wo sie sich befinden. Ähnlich wie es die Google Map API macht. Beispiel: code.google.com/apis/maps/documentation/javascript/…
Josh Johnson
Ich habe gerade herausgefunden, dass @link das kann, wovon ich spreche. Es ist nicht perfekt, aber es funktioniert. Ich werde eine separate Antwort erstellen, falls jemand anderes sie nützlich findet.
Josh Johnson