Effective code comments
Effective code comments play a vital role in enhancing code readability, facilitating collaboration, and providing valuable insights for engineers. While it's important to strive for self-documenting code, there are situations where well-placed comments can improve code understanding effectively.
Principle: Self-documenting code
One of the fundamental principles of writing clean and maintainable code is to make it self-documenting. By using descriptive and meaningful variable and function names, you can reduce the need for explicit comments. Well-designed code should convey its purpose and functionality through clear and expressive syntax. Aim to make your code as readable and understandable as possible, ensuring that future developers can easily comprehend its intent without relying heavily on comments.
When to comment
Complex logic and algorithms
Comment on sections of code that involve complex logic, algorithms, or optimizations. Explain the thought process behind the code to help future developers understand the reasoning.
/**
* Calculate the factorial of a number.
* @param {number} n - The number to calculate the factorial for.
* @returns {number} The factorial of the given number.
* @throws {Error} Throws an error if the input is a negative number.
*
* @example
* // Calculate the factorial of 5
* const result = factorial(5);
* console.log(result); // Output: 120
*/
function factorial(n: number): number {
// Base case: factorial of 0 or 1 is 1
if (n === 0 || n === 1) {
return 1;
}
let result = 1;
// Calculate factorial iteratively
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
Assumptions and constraints
When code relies on assumptions or has specific constraints, it's important to document them. This helps other developers understand the context and limitations of the code.
function calculateRectangleArea(width: number, height: number): number {
// Assumption: Both width and height are positive numbers
// Constraints: The width and height should be within reasonable limits
if (width <= 0 || height <= 0) {
return 0;
}
const area = width * height;
return area;
}
Cross-browser or compatibility issues
If the code includes specific workarounds or considerations for different browsers or compatibility issues, comments can provide insights into the reasons behind those choices.
// IE11 specific workaround: Polyfill for missing Array.includes() method
if (!Array.prototype.includes) {
Array.prototype.includes = function (value) {
// Implementation details for IE11 support
};
}
Business rules and requirements
When the code implements specific business rules or requirements, comments can provide additional context and explanations.
// Discount calculation based on customer loyalty level
if (loyaltyLevel === 'gold') {
// Apply a 10% discount for gold-level customers
discount = totalAmount * 0.1;
}
Workarounds and temporary solutions
You may encounter situations where a permanent solution is not immediately feasible or a workaround is required to address a specific issue. When implementing workarounds or temporary solutions, it's essential to document them properly to avoid confusion and ensure they are not mistaken as permanent solutions.
/**
* Workaround for issue #123
* Description: This is a temporary fix to prevent a race condition
* in the asynchronous data fetching process.
*
* TODO: [JIRA-1234] Monitor the issue and remove this workaround once a permanent solution is implemented.
*/
async function fetchData(): Promise<Data> {
// Temporary workaround for race condition
await sleep(500); // Delay added to mitigate the issue
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
When to avoid commenting
While comments can be helpful, it's important to recognize situations where commenting may not be necessary or even detrimental to the codebase. Here are some scenarios where commenting should be avoided:
Self-explanatory code
If the code is already self-explanatory and easy to understand, additional comments may only clutter the code and add unnecessary noise. Always prioritize writing clean and expressive code that is easy to comprehend without relying heavily on comments.
// Calculate the sum
const sum = a + b;
Redundant or obvious comments
Avoid comments that merely repeat what the code already expresses. Redundant comments add no value and can make the code harder to read and maintain.
// Perform the operation
const result = performOperation();
Outdated comments
Code evolves over time, and comments can quickly become outdated or misleading if not properly maintained. If a comment no longer accurately reflects the code's behavior, it's better to remove or update it accordingly.
// This code returns an object
const returnNumber = () => 12;
IDE-friendly comment formats
When you do need to include comments in your code, it's important to make them IDE-friendly. Utilizing appropriate comment formats ensures that tools and IDEs can parse and present them effectively. One widely adopted convention is the use of documentation blocks, also known as JSDoc
comments. These comments follow a specific format and can provide valuable information for both developers and IDEs.
/**
* Calculate the sum of two numbers.
* @param {number} a - The first number.
* @param {number} b - The second number.
* @returns {number} The sum of the two numbers.
*/
function sum(a, b) {
return a + b;
}
By following the JSDoc format, you can document function parameters, return types, and provide additional contextual information. IDEs can parse these comments and provide autocompletion, type information, and inline documentation, improving the developer experience and code understanding.
When using the function, IDEs can guide the user to proper usage. Take the factorial
example above:
Using JSDoc blocks
JSDoc blocks can benefit developers in several ways. Let's explore some examples:
Type annotations and documentation
JSDoc comments allow you to document the types of function parameters, return values, and variables. This is particularly useful in TypeScript to provide explicit type information and ensure type safety within your codebase.
/**
* Get the user's name.
* @param {User} user - The user object.
* @returns {string} The user's name.
*/
function getUserName(user) {
return user.name;
}
By documenting the types, you enable the IDE to perform type checking, offer auto-completion, and provide better code suggestions, leading to fewer runtime errors.
Function signatures and usage examples
JSDoc comments allow you to provide detailed explanations of function behavior and usage. You can include information about input constraints, expected outputs, and any additional side effects.
/**
* Calculate the factorial of a number.
* @param {number} n - The number to calculate the factorial for.
* @returns {number} The factorial of the given number.
* @throws {Error} Throws an error if the input is a negative number.
*
* @example
* // Calculate the factorial of 5
* const result = factorial(5);
* console.log(result); // Output: 120
*/
function factorial(n) {
if (n < 0) {
throw new Error('Input must be a non-negative number');
}
if (n === 0 || n === 1) {
return 1;
}
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
Including usage examples in your comments helps developers understand how to use the function correctly and provides clarity on expected results and potential exceptions.
Commenting practices in different code contexts
React code
- Focus on explaining the purpose and behavior of components, especially for complex or reusable components.
- Comment on component lifecycle methods and their usage.
- Provide insights into the overall structure and flow of the component hierarchy.
node.js code
- Comment on the purpose and functionality of modules, classes, or functions.
- Explain the expected input and output of functions or API endpoints.
- Clarify any important business logic, algorithms, or data transformations.
- Document external dependencies or integration points, such as database connections or third-party APIs.
Keep up to date with any latest changes or announcements by subscribing to the newsletter below.