2010-07-03 6 views
47

Editar: Esto es técnicamente una pregunta de 2 partes. Elegí la mejor respuesta que cubre la pregunta en general y está vinculada a la respuesta que maneja la pregunta específica.La mejor manera de documentar objetos anónimos y funciones con jsdoc

¿Cuál es la mejor manera de documentar objetos y funciones anónimas con 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) { 
    }; 
}; 

Ni el objeto PageRequest o la callback existen en código. Se proporcionarán a getPage() en tiempo de ejecución. Pero me gustaría poder definir qué objeto y función son.

puedo salirse con la creación del objeto PageRequest para documentar que:

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

Y eso está bien (aunque estoy abierto a mejores maneras de hacer esto).

¿Cuál es la mejor manera de documentar la función callback? Quiero que sea conocido en el documento que, por ejemplo, la función de devolución de llamada está en la forma de:

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

¿Alguna idea de cómo hacer esto?

Respuesta

39

puede documentar cosas que no lo existe en el código mediante el uso de la etiqueta @ 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(); } 

Aquí es el @name tag documentation. Usted podría encontrar name paths útil también.

+0

¡Realmente limpio! Una excelente forma de documentar devoluciones de llamadas. – oligofren

+1

¿Pero no veo cómo funciona esto para objetos anónimos? Digamos un objeto de configuración que se envía a alguna función para crear un objeto que no está visible en el alcance actual. – oligofren

+1

Si no desea utilizar la etiqueta '@ name' para dar un nombre a su objeto anónimo, describa el objeto donde se usa, que sería el cuerpo de la etiqueta' @ param' para su ejemplo de objeto de configuración. – Eric

0

Puede usar @see para vincular a otro método dentro de la misma clase. El método nunca se usaría, simplemente estaría allí para fines de documentación.

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

Si está utilizando algún tipo de sistema de compilación, el método ficticio podría omitirse fácilmente de la compilación.

+0

Gracias, no. Lo estoy haciendo actualmente (sin ifdef) y funciona, pero me gustaría que el usuario pueda ver de inmediato que es una función que acepta los params X e Y sin abandonar el lugar en el que se encuentran. Similar a cómo lo hace la API de google api. ejemplo: http://code.google.com/apis/maps/documentation/javascript/reference.html#DirectionsService –

+0

Acabo de descubrir que @link puede hacer lo que estoy diciendo. No es perfecto, pero funciona. Crearé una respuesta por separado en caso de que alguien más lo encuentre útil. –

1

@link pueden agregar enlaces en línea a métodos y clases.

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

No es ideal, pero hace su trabajo.

1

Las anotaciones del compilador de cierres de Google tienen Type Expressions para esto, que incluye la capacidad de indicar el tipo para argumentos específicos, tipo de retorno e incluso esto. Muchas bibliotecas están siguiendo las Anotaciones del Compilador de Cierre de Google, porque quieren usarlo para reducir su código. Entonces tiene algo de impulso. El inconveniente es que no veo una forma de dar la descripción.

Para proporcionar la descripción, quizás el enfoque de JSDoc Toolkit Parameters With Properties funcionaría (consulte la parte inferior de la página). Es lo que estoy haciendo en este momento. JSDoc Toolkit está preparándose para comenzar a trabajar en V3, por lo que los comentarios podrían ser buenos.

7

Para complementar la respuesta de studgeek, he proporcionado un ejemplo que muestra lo que JsDoc with Google Closure Compiler le permite hacer.

Tenga en cuenta que los tipos anónimos documentados se eliminan del archivo minificado generado y el compilador asegura que se pasen los objetos válidos (cuando sea posible).Sin embargo, incluso si no usa el compilador, puede ayudar al próximo desarrollador y herramientas como WebStorm (IntelliJ) a entenderlo y darle la finalización del código.

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

Hola, esta parece ser la respuesta más elegante, sin embargo, la salida JSDoc solo contiene 'función' sin la escritura de parámetros específicos. Estoy usando jsdoc '3.4.0'. ¿Esta sintaxis no es totalmente compatible? –

+1

@PeteV. No he seguido el nivel de sincronización entre jsdoc y el compilador de cierre. Te recomendaría que busques generadores de documentos alternativos que estén diseñados para trabajar con el compilador de cierre (ya que es un superconjunto del estándar jsdoc). Pruebe http://plovr.com/, http://www.seehuhn.de/pages/jvjsdoc o https://github.com/google/closure-compiler/wiki/Create-HTML-Docs-using-JSDoc. He pasado al uso de TypeScript para agregar mecanografía estática a JavaScript –

26

Puede utilizar @callback o @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) { ... } 
+0

Referencia: http://usejsdoc.org/tags-callback.html –

+2

@ChrisMoschini Gracias. La etiqueta '@ callback' en la respuesta se vinculó a la página de documentación correspondiente. – kzh

Cuestiones relacionadas