
CodeCraftinghub
Every developer has seen it: a helpful comment that lies. The code was refactored, the comment remained, and now it actively misleads the next engineer. The root cause is a fundamental truth comments and code live separate lives. When you change code, you rarely remember to update the comment. Over time, this creates a silent swamp of outdated, even dangerous, documentation.
The solution isn’t to ban comments. It’s to treat them as the exception, not the rule. By writing self explanatory code, you eliminate the need for most comments entirely. Your code becomes the single source of truth clean, expressive, and impossible to go out of sync.
In this article, we’ll explore how to write professional, self‑documenting JavaScript. You’ll see concrete examples that make comments redundant and learn patterns that keep your codebase maintainable.
Consider this typical snippet:
At first glance, the comments seem helpful. But what happens when the discount logic changes to a tiered system? Or the tax rate becomes dynamic? The comments will almost certainly stay as they are, creating a trap for anyone who trusts them. Worse, the code itself is noisy with boilerplate and magic numbers.
Now let’s rewrite it without a single explanatory comment, using only expressive naming and structure.
Names are the most powerful tool for self‑documentation. A well‑chosen function or variable name tells you what and why.
What changed?
When a function does only one thing and its name describes that thing perfectly, comments become unnecessary.
Now the code reads like a story. You don’t need a comment to understand the permission logic the function names and composition tell you everything.
Destructuring, default parameters, and object shorthand can turn cryptic code into clear declarations.
The destructured parameter makes it obvious what inputs are expected. The default value for role is right where you need it. The code is compact yet perfectly clear.
Comments that restate what the code does are noise. The code itself can and should—do that.
When you use higher‑order functions like reduce, map, or filter, the intent is embedded in the method name. You no longer need comments to explain iteration.
Magic numbers are a common source of “what” comments. Turn them into named constants.
Now the condition reads like a business rule. Any future change to the threshold is isolated to the constant, and the function name tells you exactly what’s being checked.
Self‑explanatory code doesn’t mean never write comments. It means using comments for things code cannot express:
Example of a good comment:
Conclusion
Comments are not evil, but they are a liability when used as a crutch for unclear code. Every time you write a comment, ask yourself: Can I rewrite the code so this comment becomes unnecessary?
Professional engineers know that code is read far more often than it is written. By investing in self‑explanatory code clear names, small functions, meaningful constants, and expressive modern syntax you build a codebase that is a joy to read, safe to change, and immune to the silent rot of outdated comments.
The next time you’re about to add a comment, let the code speak for itself. Your future self (and your teammates) will thank you.
Happy coding, and may your code always be its own best documentation.

AI writes fast. It doesn't write secure. Hardcoded secrets, injection flaws, and over-privileged logic slip in constantly because models solve tasks, not threat models. Here's the practical checklist to own your code not just mop up after the robot.

AI writes fast. You debug slow. Here's how to flip that script and actually own your codebase again.
Join the newsletter for practical insights on architecture, code quality, and developer workflow.
// Calculate total with tax
// tax rate is 0.08 (8%)
// apply discount if total > 100
function calc(cart) {
let total = 0;
for (let i = 0; i < cart.length; i++) {
total += cart[i].price * cart[i].quantity;
}
// apply discount
if (total > 100) {
total = total * 0.9;
}
// add tax
total = total * 1.08;
return total;
}const TAX_RATE = 0.08;
const DISCOUNT_THRESHOLD = 100;
const DISCOUNT_RATE = 0.9;
function calculateCartTotalAfterDiscountAndTax(cart) {
const subtotal = calculateSubtotal(cart);
const discountedTotal = applyDiscount(subtotal);
return addTax(discountedTotal);
}
function calculateSubtotal(cart) {
return cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
function applyDiscount(amount) {
return amount > DISCOUNT_THRESHOLD ? amount * DISCOUNT_RATE : amount;
}
function addTax(amount) {
return amount * (1 + TAX_RATE);
}// Needs a comment
// check if user has permission to edit this document
function canEdit(user, doc) {
return user.role === 'admin' || doc.ownerId === user.id;
}
// Self‑explanatory
function isAdmin(user) {
return user.role === 'admin';
}
function isOwner(user, doc) {
return doc.ownerId === user.id;
}
function canEditDocument(user, doc) {
return isAdmin(user) || isOwner(user, doc);
}// Before: comment needed to explain what's happening
function createUser(data) {
// extract first and last name from the full name
const fullName = data.fullName.split(' ');
const firstName = fullName[0];
const lastName = fullName[1];
// default role to 'user'
const role = data.role || 'user';
return { firstName, lastName, role };
}
// After: self‑explanatory with modern syntax
function createUser({ fullName, role = 'user' }) {
const [firstName, lastName] = fullName.split(' ');
return { firstName, lastName, role };
}// Redundant "what" comments
// loop through products
for (let i = 0; i < products.length; i++) {
// add to total
total += products[i].price;
}
// Code that needs no explanation
const totalPrice = products.reduce((sum, product) => sum + product.price, 0);// Cryptic
if (user.points > 1000 && user.purchases > 5) {
user.tier = 'gold';
}
// Self‑explaining
const GOLD_TIER_MIN_POINTS = 1000;
const GOLD_TIER_MIN_PURCHASES = 5;
function isEligibleForGoldTier(user) {
return user.points >= GOLD_TIER_MIN_POINTS &&
user.purchases >= GOLD_TIER_MIN_PURCHASES;
}
if (isEligibleForGoldTier(user)) {
user.tier = 'gold';
}/**
* Fetches user data with retry logic.
* Why: The external user service is unreliable and may fail with 5xx errors.
* We retry up to 3 times with exponential backoff to increase reliability.
*/
async function fetchUserWithRetry(userId) {
// implementation...
}
Comments
No approved comments yet.