L'art subtil d'ajouter des commentaires de code en JavaScript
Déboguer du code sans commentaires, c'est comme être un détective essayant de résoudre un crime, mais le seul témoin parle dans une langue étrangère, et il y a des personnes influentes (clients) qui vous poussent à résoudre l'affaire hier.
source de l'image — Deux hommes regardant un ordinateur portable · Photo stock gratuite (pexels.com)
Introduction
L'ajout de commentaires de code est important pour plusieurs raisons :
1. Lisibilité du code. Les commentaires aident les développeurs à comprendre le but du code en l'expliquant dans un langage simple, ce qui facilite la lecture et la modification.
2. Entretien. Les commentaires vous aident à vous souvenir de l'objectif de votre code, ce qui facilite sa maintenance et sa mise à jour à l'avenir sans causer accidentellement de problèmes.
3. Collaboration. Les commentaires évitent les erreurs et les interprétations erronées dans les projets collaboratifs en fournissant un contexte pour les modifications de code, garantissant ainsi que tout le monde est sur la même longueur d'onde.
4. Documents. Les commentaires du code clarifient l'objectif et la fonctionnalité, garantissant la conformité aux normes et aux meilleures pratiques de l'industrie. Ils rendent le code plus lisible, maintenable et plus facile à utiliser, tout comme le guide d'instructions LEGO pour la construction d'un ensemble.
En prenant le temps d'ajouter des commentaires significatifs et précis au code, les développeurs peuvent améliorer la qualité globale et la maintenabilité de leurs projets.
Modèle mental pour ajouter des commentaires au code
Avant d'écrire des commentaires autour d'un morceau de code, il est important d'être clair sur l'intention de le faire. Un commentaire de code est un mécanisme de communication qui doit communiquer les aspects suivants du code :
1. Objectif. Expliquez le but du code, quel problème il résout et pourquoi il existe.
2. Entrée. Spécifiez les entrées requises par le code, y compris leurs types, les valeurs attendues et si elles sont facultatives ou obligatoires.
3. Sortie. Spécifiez la sortie produite par le code, y compris son type et tous les détails pertinents.
4. Utilisation. Fournissez des exemples d'utilisation du code, y compris des extraits de code pertinents.
5. Liaison. Ajoutez des liens vers le code associé et les ressources externes.
6. Meilleures pratiques. Mettez en évidence les meilleures pratiques ou les pièges liés au code.
En suivant le bon modèle mental, les développeurs peuvent s'assurer que leur code est bien documenté, facile à comprendre et maintenable dans le temps.
Cohérence et standardisation
Il est crucial de maintenir la cohérence dans le formatage et le style des commentaires dans toute la base de code. L'utilisation d'un outil tel que JS Doc (documentation JavaScript), qui est un ensemble de normes de documentation et d'outils pour documenter le code JavaScript, est une bonne option.
Voici quelques-unes des fonctionnalités de JS Doc :
- Il utilise des balises pour capturer des informations sur la structure, la fonction, les paramètres, les valeurs de retour et d'autres détails du code afin de créer une référence lisible par l'homme pour les autres développeurs.
- Une balise JS Doc commence par un
@symbole, suivi du nom de la balise et de toute information pertinente. Par exemple, laparambalise est utilisée pour décrire un paramètre de fonction, tandis que lareturnsbalise est utilisée pour décrire la valeur de retour d'une fonction. - Il peut générer de la documentation au format HTML ou d'autres formats à partir de commentaires en ligne dans le code source.
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
Balises de document JS couramment utilisées
Jetons un coup d'œil à quelques balises JS Doc qui sont utilisées assez fréquemment.
@todo
/**
* @todo Add details about the factorial calculation and edge cases.
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @todo Add an example usage of the callback function.
*/
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
La première étape consiste à décrire ce que fait le code. @descriptionLa balise est utilisée pour fournir une description détaillée d'une fonction, d'un objet ou d'une propriété. Voyons à quoi ressemble le code après avoir ajouté cette balise.
/**
* @description A function that calculates the factorial of a number using recursion.
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*/
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
Voici la partie où il est dit quelle entrée le code prend. @paramtag est utilisé pour décrire les paramètres d'une fonction. En l'ajoutant à l'exemple, le code ressemble à ceci :
/**
* @description A function that calculates the factorial of a number using recursion.
*
* @param {number} n - The number for which to calculate the factorial.
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*
* @param {number} n - The number for which to calculate the factorial.
* @param {function} callback - The function to call with the result of the calculation.
*/
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
Jusqu'à présent, nous savons ce que fait la fonction et les entrées qu'elle prend. Vient ensuite la description de la valeur de retour d'une fonction. L'ajout @returnsà l'exemple donne au code l'aspect suivant :
/**
* @description A function that calculates the factorial of a number using recursion.
*
* @param {number} n - The number for which to calculate the factorial.
*
* @returns {number} The factorial of `n`.
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*
* @param {number} n - The number for which to calculate the factorial.
* @param {function} callback - The function to call with the result of the calculation.
*
* @returns {void}
*/
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
Il y aura des moments où la fonction rencontrera des erreurs et ne pourra pas produire les résultats souhaités. @throwsaide à documenter ces scénarios. L'ajout @throwsà l'exemple donne au code l'aspect suivant :
/**
* @description A function that calculates the factorial of a number using recursion.
*
* @param {number} n - The number for which to calculate the factorial.
*
* @returns {number} The factorial of `n`.
*
* @throws {TypeError} If the input is not a number.
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*
* @param {number} n - The number for which to calculate the factorial.
* @param {function} callback - The function to call with the result of the calculation.
*
* @returns {void}
*/
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
Parfois, le consommateur ou l'invocateur du code n'est pas intéressé par les détails d'implémentation de bas niveau et est préoccupé par l'invocation et l'obtention des résultats attendus. @exampleLa balise est utilisée pour fournir un exemple d'utilisation d'une fonction ou d'un objet. L'ajout @exampleà l'exemple donne au code l'aspect suivant :
/**
* @description A function that calculates the factorial of a number using recursion.
*
* @param {number} n - The number for which to calculate the factorial.
*
* @returns {number} The factorial of `n`.
*
* @throws {TypeError} If the input is not a number.
*
* @example
* factorial(5);
* // returns 120
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*
* @param {number} n - The number for which to calculate the factorial.
* @param {function} callback - The function to call with the result of the calculation.
*
* @returns {void}
*
* @example
* factorialWithCallback(5, (error, result) => {
* if (error) {
* console.error(error);
* } else {
* console.log(result);
* }
* });
* // logs { input: 5, output: 120 }
*/
function factorialWithCallback(n, callback) {
try {
const result = {
input: n,
output: factorial(n),
};
callback(null, result);
} catch (error) {
callback(error);
}
}
La @typebalise JSDoc est utilisée pour spécifier le type d'une variable, d'une fonction ou d'une expression. Il fournit des informations supplémentaires sur le type d'entité documentée et contribue à la lisibilité et à la maintenabilité du code.
La @typedefbalise JSDoc, quant à elle, est utilisée pour définir un type personnalisé. Cela peut être utile dans des projets complexes où vous avez des structures ou des types de données personnalisés qui doivent être documentés. Le type personnalisé défini avec @typedefpeut ensuite être référencé avec la @typebalise dans d'autres parties du code.
Essentiellement, @typedefest utilisé pour définir un type personnalisé, tandis que @typeest utilisé pour spécifier le type d'une entité.
La @propertybalise JSDoc est utilisée pour documenter les propriétés d'un objet ou d'une classe. Il est généralement utilisé conjointement avec @typedefpour documenter la structure d'un objet ou d'une classe. La @propertybalise spécifie le nom et le type d'une propriété, ainsi qu'une description de son objectif.
L'ajout @typede , @typedefet @propertyà l'exemple donne au code l'aspect suivant :
/**
* @typedef {Object} FactorialResult
*
* @property {number} input - The input to the factorial function.
* @property {number} output - The output of the factorial function.
*/
/**
* @description A function that calculates the factorial of a number using recursion.
*
* @param {number} n - The number for which to calculate the factorial.
*
* @returns {number} The factorial of `n`.
*
* @throws {TypeError} If the input is not a number.
*
* @example
* factorial(5);
* // returns 120
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*
* @param {number} n - The number for which to calculate the factorial.
* @param {function} callback - The function to call with the result of the calculation.
*
* @returns {void}
*
* @example
* factorialWithCallback(5, (error, result) => {
* if (error) {
* console.error(error);
* } else {
* console.log(result);
* }
* });
* // logs { input: 5, output: 120 }
*/
function factorialWithCallback(n, callback) {
/**
* @type {FactorialResult}
*/
const result = {
input: n,
output: factorial(n),
};
try {
callback(null, result);
} catch (error) {
callback(error);
}
}
@callback
/**
* @typedef {Object} FactorialResult
*
* @property {number} input - The input to the factorial function.
* @property {number} output - The output of the factorial function.
*/
/**
* @callback FactorialCallback
*
* @param {Error} error - The error that occurred during the calculation, if any.
* @param {FactorialResult} result - The result of the calculation.
*/
/**
* @description A function that calculates the factorial of a number using recursion.
*
* @param {number} n - The number for which to calculate the factorial.
*
* @returns {number} The factorial of `n`.
*
* @throws {TypeError} If the input is not a number.
*
* @example
* factorial(5);
* // returns 120
*/
function factorial(n) {
if (typeof n !== "number") {
throw new TypeError("Input must be a number");
}
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
/**
* @description A version of the factorial function that returns the result via a callback.
*
* @param {number} n - The number for which to calculate the factorial.
* @param {FactorialCallback} callback - The function to call with the result of the calculation.
*
* @returns {void}
*
* @example
* factorialWithCallback(5, (error, result) => {
* if (error) {
* console.error(error);
* } else {
* console.log(result);
* }
* });
* // logs { input: 5, output: 120 }
*/
function factorialWithCallback(n, callback) {
/**
* @type {FactorialResult}
*/
const result = {
input: n,
output: factorial(n),
};
try {
callback(null, result);
} catch (error) {
callback(error);
}
}
Le FactorialCallbacktype est alors référencé dans la @parambalise du paramètre callback de la factorialWithCallbackfonction.
Exemple/démo
Un aperçu de l'extrait ci-dessus et de la documentation qu'il génère à l'aide de JS Doc peut être consulté ici .
Veuillez noter que l'exemple est une mise en œuvre très simplifiée pour montrer au lecteur le potentiel qui peut être débloqué une fois que toutes ces techniques sont comprises et mises en œuvre dans leurs projets.
Résumé
Dans un monde plein de bases de code complexes et complexes, les commentaires de code sont un ami dont nous avons tous besoin. Avec des avantages allant d'une meilleure lisibilité du code à une documentation générée automatiquement, des outils comme JS Doc sont essentiels à toute boîte à outils de développement.
Que vous soyez un développeur chevronné ou débutant, prendre le temps de documenter votre code de manière standardisée profitera non seulement au produit à court terme, mais assurera également la longévité et la maintenabilité de la base de code pour les années à venir.
Je vous encourage à utiliser ces systèmes dans vos projets. Croyez-moi, votre futur moi vous en remerciera !
![Qu'est-ce qu'une liste liée, de toute façon? [Partie 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































