Clean Code in JavaScript: Principles and Examples for Beginners
Clean Code is not just a trendy concept, but a fundamental skill for any professional developer. In the world of JavaScript (especially in the Node.js environment), code is written quickly, but maintaining it without clear principles becomes a real nightmare. This article is for beginners who want to write not just working code, but beautiful, readable, and scalable code.
Clean Code is code that is easy to read, easy to modify, and easy to test. It doesn't make you want to rewrite it from scratch. Let's break down the main principles with practical examples.
1. Naming Variables and Functions: Tell the Truth
The simplest yet most difficult rule — the name should reflect the essence. Don't save characters, save time on understanding.
Bad (unclear):
const d = new Date();const arr = ['apple', 'banana', 'grape'];const fn = (x) => x * 2;Good (readable):
const currentDate = new Date();const fruitList = ['apple', 'banana', 'grape'];const doubleValue = (value) => value * 2;Naming rules:
- Variables — nouns (user, productList, errorMessage).
- Functions — verbs (getUser, calculateTotal, validateEmail).
- Boolean values — start with
is,has,should(isActive, hasPermission, shouldUpdate). - Avoid magic numbers — extract them into constants.
// Badconst t = 3600000; // What is this number?
// Goodconst MILLISECONDS_IN_AN_HOUR = 3600000;const timeout = MILLISECONDS_IN_AN_HOUR;2. Functions: One Step — One Action
The Single Responsibility Principle also applies to functions. A function should do one thing and do it well.
Bad (does everything at once):
function processUserData(user) { const fullName = `${user.firstName} ${user.lastName}`; const email = user.email.toLowerCase(); const isValid = email.includes('@'); if (isValid) { const result = { fullName, email }; saveToDatabase(result); sendWelcomeEmail(email); return result; } else { throw new Error('Invalid email'); }}Good (split into small functions):
function buildFullName(firstName, lastName) { return `${firstName} ${lastName}`;}
function normalizeEmail(email) { return email.toLowerCase().trim();}
function isValidEmail(email) { return email.includes('@');}
function processUserData(user) { const fullName = buildFullName(user.firstName, user.lastName); const email = normalizeEmail(user.email); if (!isValidEmail(email)) { throw new Error('Invalid email'); } const result = { fullName, email }; saveToDatabase(result); sendWelcomeEmail(email); return result;}Such code is easy to test, easy to modify, and easy to understand.
3. Managing Complexity: Avoid Deep Nesting
Deep nesting of if and for is the enemy of readability. Use early return and Guard Clauses.
Bad (deep hell):
function processOrder(order) { if (order) { if (order.isPaid) { if (order.items.length > 0) { // ... 50 lines of code } } }}Good (flat structure):
function processOrder(order) { if (!order) { return; }