Naming
javascript
// Bad
const d = new Date();
// Good
const currentDate = new Date();
// Bad
function getUser(u) { return u.name; }
// Good
function getUserName(user) { return user.name; }Functions
javascript
// Bad: Too long, does too much
function processUser(userData) {
// 50 lines of validation
// 30 lines of transformation
// 40 lines of database save
// 20 lines of email sending
}
// Good: Single responsibility
function validateUser(userData) { /* ... */ }
function transformUser(userData) { /* ... */ }
function saveUser(user) { /* ... */ }
function sendWelcomeEmail(user) { /* ... */ }
async function registerUser(userData) {
const validated = validateUser(userData);
const transformed = transformUser(validated);
const user = await saveUser(transformed);
await sendWelcomeEmail(user);
return user;
}Comments
javascript
// Bad: Comment explains what
// Check if user is logged in
if (user.isLoggedIn) { /* ... */ }
// Good: Code is self-explanatory
if (user.isLoggedIn) { /* ... */ }
// Bad: Obvious comment
// Increment counter
count++;
// Good: Comment explains WHY
// Using setTimeout to avoid race condition in event loop
setTimeout(() => processNext(), 0);DRY (Don't Repeat Yourself)
javascript
// Bad: Duplicated logic
function calculateAreaCircle(radius) {
return Math.PI * radius * radius;
}
function calculateCircumferenceCircle(radius) {
return 2 * Math.PI * radius;
}
// Good: Extract common logic
const circleMath = {
area: (r) => Math.PI * r * r,
circumference: (r) => 2 * Math.PI * r
};Error Handling
javascript
// Bad: Silent failures
function parseJSON(str) {
try {
return JSON.parse(str);
} catch (e) {
return null;
}
}
// Good: Handle errors appropriately
function parseJSON(str, defaultValue = null) {
try {
return JSON.parse(str);
} catch (e) {
logger.error('JSON parse failed', { error: e.message, input: str });
return defaultValue;
}
}Code Smells
- 1Long functions: Break down into smaller functions
- 2Duplicated code: Extract to functions/variables
- 3Large parameter lists: Use objects
- 4Feature envy: Function uses more of other objects
- 5Shotgun surgery: Changes require many small changes
Refactoring
javascript
// Before: Nested conditionals
function processOrder(order) {
if (order) {
if (order.items) {
if (order.items.length > 0) {
// Process order
}
}
}
}
// After: Early returns
function processOrder(order) {
if (!order) return;
if (!order.items) return;
if (order.items.length === 0) return;
// Process order
}Clean code is not about following rules blindly, but about writing code that others (and future you) can understand and modify.