La sottile arte di aggiungere commenti al codice in JavaScript
Il debug del codice senza commenti è come essere un detective che cerca di risolvere un crimine, ma l'unico testimone parla in una lingua straniera e ci sono alcune persone influenti (clienti) con il fiato sul collo per risolvere il caso di ieri.
fonte dell'immagine — Due uomini che guardano un laptop · Foto stock gratis (pexels.com)
introduzione
L'aggiunta di commenti al codice è importante per diversi motivi:
1. Leggibilità del codice. I commenti aiutano gli sviluppatori a comprendere lo scopo del codice spiegandolo in un linguaggio semplice, facilitandone la lettura e la modifica.
2. Manutenzione. I commenti ti aiutano a ricordare lo scopo del tuo codice, semplificando la manutenzione e l'aggiornamento in futuro senza causare problemi accidentali.
3. Collaborazione. I commenti prevengono errori e interpretazioni errate nei progetti collaborativi fornendo un contesto per le modifiche al codice, assicurando che tutti siano sulla stessa pagina.
4. Documentazione. I commenti al codice forniscono chiarezza sullo scopo e sulla funzionalità, garantendo la conformità con gli standard e le best practice del settore. Rendono il codice più leggibile, manutenibile e più facile da usare, proprio come le istruzioni LEGO nella costruzione di un set.
Prendendosi il tempo necessario per aggiungere commenti significativi e accurati al codice, gli sviluppatori possono migliorare la qualità complessiva e la manutenibilità dei loro progetti.
Modello mentale per l'aggiunta di commenti al codice
Prima di scrivere commenti su un pezzo di codice, è importante essere chiari sull'intento di farlo. Un commento al codice è un meccanismo di comunicazione che dovrebbe comunicare i seguenti aspetti del codice:
1. Scopo. Spiega lo scopo del codice, quale problema risolve e perché esiste.
2. Ingresso. Specificare gli input richiesti dal codice, inclusi i loro tipi, i valori previsti e se sono facoltativi o obbligatori.
3. Uscita. Specificare l'output prodotto dal codice, incluso il tipo e tutti i dettagli pertinenti.
4. Utilizzo. Fornisci esempi di come utilizzare il codice, inclusi snippet di codice pertinenti.
5. Collegamento. Aggiungi collegamenti al codice correlato e alle risorse esterne.
6. Migliori pratiche. Evidenzia eventuali best practice o trucchi relativi al codice.
Seguendo il giusto modello mentale, gli sviluppatori possono garantire che il loro codice sia ben documentato, facile da capire e gestibile nel tempo.
Coerenza e standardizzazione
È fondamentale mantenere la coerenza nella formattazione e nello stile dei commenti in tutta la base di codice. L'utilizzo di uno strumento come JS Doc (documentazione JavaScript), che è un insieme di standard di documentazione e strumenti per documentare il codice JavaScript, è una buona opzione.
Di seguito sono riportate alcune delle funzionalità di JS Doc:
- Utilizza i tag per acquisire informazioni sulla struttura, la funzione, i parametri, i valori restituiti e altri dettagli del codice per creare un riferimento leggibile per altri sviluppatori.
- Un tag JS Doc inizia con un
@simbolo, seguito dal nome del tag e da eventuali informazioni pertinenti. Ad esempio, ilparamtag viene utilizzato per descrivere un parametro di funzione, mentre ilreturnstag viene utilizzato per descrivere il valore restituito di una funzione. - Può generare documentazione in HTML o altri formati dai commenti incorporati nel codice sorgente.
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);
}
}
Tag JS Doc di uso comune
Diamo un'occhiata a un paio di tag JS Doc che vengono utilizzati abbastanza frequentemente.
@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);
}
}
Il primo passo è descrivere cosa fa il codice. @descriptiontag viene utilizzato per fornire una descrizione dettagliata di una funzione, oggetto o proprietà. Vediamo come appare il codice dopo aver aggiunto questo tag.
/**
* @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);
}
}
Qui arriva la parte in cui viene detto quale input prende il codice. @paramtag è usato per descrivere i parametri di una funzione. Aggiungendolo all'esempio, il codice appare così:
/**
* @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);
}
}
Finora sappiamo cosa fa la funzione e gli input che richiede. Poi viene descritto il valore di ritorno di una funzione. L'aggiunta @returnsall'esempio rende il codice simile a questo:
/**
* @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);
}
}
Ci saranno momenti in cui la funzione incontrerà errori e non sarà in grado di produrre i risultati desiderati. @throwsaiuta a documentare questi scenari. L'aggiunta @throwsall'esempio rende il codice simile a questo:
/**
* @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);
}
}
A volte, il consumatore o l'invocatore del codice non è interessato ai dettagli di implementazione di basso livello ed è preoccupato per l'invocazione e per ottenere i risultati attesi. @exampletag viene utilizzato per fornire un esempio di come utilizzare una funzione o un oggetto. L'aggiunta @exampleall'esempio rende il codice simile a questo:
/**
* @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);
}
}
Il @typetag JSDoc viene utilizzato per specificare il tipo di una variabile, funzione o espressione. Fornisce informazioni aggiuntive sul tipo di entità documentata e aiuta con la leggibilità e la manutenibilità del codice.
Il @typedeftag JSDoc, invece, viene utilizzato per definire un tipo personalizzato. Ciò può essere utile in progetti complessi in cui si dispone di strutture o tipi di dati personalizzati che devono essere documentati. Il tipo personalizzato definito con @typedefpuò quindi essere referenziato con il @typetag in altre parti del codice.
In sostanza, @typedefviene utilizzato per definire un tipo personalizzato, mentre @typeviene utilizzato per specificare il tipo di un'entità.
Il @propertytag JSDoc viene utilizzato per documentare le proprietà di un oggetto o di una classe. Viene tipicamente utilizzato insieme a @typedefper documentare la struttura di un oggetto o di una classe. Il @propertytag specifica il nome e il tipo di una proprietà, nonché una descrizione del suo scopo.
L'aggiunta @typedi , @typedef, e @propertyall'esempio rende il codice simile a questo:
/**
* @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);
}
}
Il FactorialCallbacktipo viene quindi referenziato nel @paramtag per il parametro di callback della factorialWithCallbackfunzione.
Esempio/Dimostrazione
Un'anteprima del suddetto frammento e della documentazione che genera utilizzando JS Doc può essere verificata qui .
Si prega di notare che l'esempio è un'implementazione molto semplificata per mostrare al lettore il potenziale che può essere sbloccato una volta che tutte queste tecniche saranno comprese e implementate nei loro progetti.
Riepilogo
In un mondo pieno di basi di codice complesse e intricate, i commenti al codice sono un amico di cui tutti abbiamo bisogno. Con vantaggi che vanno dalla migliore leggibilità del codice alla documentazione generata automaticamente, strumenti come JS Doc sono essenziali per qualsiasi toolkit di sviluppo.
Che tu sia uno sviluppatore esperto o che abbia appena iniziato, dedicare del tempo a documentare il tuo codice in modo standardizzato non solo gioverà al prodotto a breve termine, ma assicurerà anche la longevità e la manutenibilità della base di codice per gli anni a venire.
Ti incoraggio a utilizzare questi sistemi nei tuoi progetti. Fidati di me, il tuo sé futuro ti ringrazierà per questo!

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































